diff --git a/src/main/kotlin/application/VisualisationChart.kt b/src/main/kotlin/application/VisualisationChart.kt new file mode 100644 index 0000000..9184890 --- /dev/null +++ b/src/main/kotlin/application/VisualisationChart.kt @@ -0,0 +1,10 @@ +package application + +import javafx.scene.chart.Axis +import javafx.scene.chart.ScatterChart + +class VisualisationChart(xAxis: Axis?, yAxis: Axis?) : ScatterChart(xAxis, yAxis) { + + + +} \ No newline at end of file diff --git a/src/main/kotlin/application/controller/DataPanelController.kt b/src/main/kotlin/application/controller/DataPanelController.kt new file mode 100644 index 0000000..de69ab5 --- /dev/null +++ b/src/main/kotlin/application/controller/DataPanelController.kt @@ -0,0 +1,276 @@ +package application.controller + +import application.model.* +import javafx.collections.FXCollections +import javafx.collections.ObservableList +import javafx.fxml.FXML +import javafx.fxml.Initializable +import javafx.scene.chart.CategoryAxis +import javafx.scene.chart.NumberAxis +import javafx.scene.chart.ScatterChart +import javafx.scene.chart.XYChart.Data +import javafx.scene.chart.XYChart.Series +import javafx.scene.control.ListCell +import javafx.scene.control.ListView +import java.net.URL +import java.util.* + + +class DataPanelController : Initializable, SelectedVesselListener { + private var dataList: ObservableList>> = FXCollections.observableArrayList() + private lateinit var timeData: ArrayList + + @FXML + var dataListView = ListView>>() + + @FXML + var xaxisNumber: CategoryAxis = CategoryAxis() + + @FXML + var yaxisNumber: NumberAxis = NumberAxis() + + @FXML + lateinit var scatterChartNumber: ScatterChart + + @FXML + var xaxisCategory: CategoryAxis = CategoryAxis() + + @FXML + var yaxisCategory: CategoryAxis = CategoryAxis() + + @FXML + lateinit var scatterChartCategory: ScatterChart + + override fun initialize(location: URL?, resources: ResourceBundle?) { + xaxisNumber.animated = false + yaxisNumber.animated = false + xaxisCategory.animated = false + yaxisCategory.animated = false + setObservableSelectedVesselListener() + dataListView.items = dataList + + + + dataListView.setCellFactory { + object : ListCell>?>() { + override fun updateItem(item: Pair>?, empty: Boolean) { + super.updateItem(item, empty) + text = if (empty) { + null + } else { + item?.first + } + } + } + } + + dataListView.selectionModel.selectedItemProperty().addListener { _, _, newValue -> + if (newValue == null){ + scatterChartCategory.data.clear() + scatterChartNumber.data.clear() + return@addListener + } + val serieNumber = Series() + val serieString = Series() + + val getValueVisitorX = GetValueVisitor() + val getValueVisitorY = GetValueVisitor() + + + for (x in 0 until newValue?.second?.size!!) { + timeData[x]?.accept(getValueVisitorX) + newValue.second[x]?.accept(getValueVisitorY) + + if (getValueVisitorY.value.toDoubleOrNull() == null){ + serieString.data.add(Data(getValueVisitorX.value, getValueVisitorY.value)) + } else{ + serieNumber.data.add(Data(getValueVisitorX.value, getValueVisitorY.value.toDouble())) + } + + } + + scatterChartNumber.data.clear() + scatterChartCategory.data.clear() + + if (getValueVisitorY.value.toDoubleOrNull() == null){ + serieString.data.add(Data(getValueVisitorX.value, getValueVisitorY.value)) + scatterChartCategory.data.addAll(serieString) + setChartCategoryVisible() + xaxisCategory.label = "Date" + yaxisCategory.label = newValue.first + } else{ + serieNumber.data.add(Data(getValueVisitorX.value, getValueVisitorY.value.toDouble())) + scatterChartNumber.data.addAll(serieNumber) + setChartNumberVisible() + xaxisNumber.label = "Date" + yaxisNumber.label = newValue.first + } + + } + + } + + private fun setChartCategoryVisible(){ + scatterChartCategory.isVisible = true + scatterChartNumber.isVisible = false + } + + private fun setChartNumberVisible(){ + scatterChartCategory.isVisible = false + scatterChartNumber.isVisible = true + } + + private fun setObservableSelectedVesselListener() { + observableSelectedVessel.listeners.add(this) + } + + private fun populateTime(vessel: Vessel): ArrayList { + val allTime: ArrayList = vessel.getAllTime() + allTime.sortBy { (it as Time).value } + + return allTime + } + + private fun populateLatitude(vessel: Vessel): ArrayList { + val allLatitude: ArrayList = vessel.getAllLatitude() + allLatitude.sortBy { (it as Latitude).value } + + return allLatitude + } + + private fun populateLongitude(vessel: Vessel): ArrayList { + val allLongitude: ArrayList = vessel.getAllLongitude() + allLongitude.sortBy { (it as Longitude).value } + + return allLongitude + } + + private fun populateSpeedOverGround(vessel: Vessel): ArrayList { + val allSpeedOverGround: ArrayList = vessel.getAllSpeedOverGround() + allSpeedOverGround.sortBy { (it as SpeedOverGround).value } + + return allSpeedOverGround + } + + private fun populateCourseOverGround(vessel: Vessel): ArrayList { + val allCourseOverGround: ArrayList = vessel.getAllCourseOverGround() + allCourseOverGround.sortBy { (it as CourseOverGround).value } + + return allCourseOverGround + } + + private fun populateHeading(vessel: Vessel): ArrayList { + val allHeading: ArrayList = vessel.getAllHeading() + allHeading.sortBy { (it as Heading).value } + + return allHeading + } + + private fun populatVesselName(vessel: Vessel): ArrayList { + val allVesselName: ArrayList = vessel.getAllVesselName() + allVesselName.sortBy { (it as VesselName).value } + + return allVesselName + } + + private fun populatIMO(vessel: Vessel): ArrayList { + val allIMO: ArrayList = vessel.getAllIMO() + allIMO.sortBy { (it as IMO).value } + + return allIMO + } + + private fun populatCallSign(vessel: Vessel): ArrayList { + val allCallSign: ArrayList = vessel.getAllCallSign() + allCallSign.sortBy { (it as CallSign).value } + + return allCallSign + } + + private fun populatVesselType(vessel: Vessel): ArrayList { + val allVesselType: ArrayList = vessel.getAllVesselType() + allVesselType.sortBy { (it as VesselType).value } + + return allVesselType + } + + private fun populatStatus(vessel: Vessel): ArrayList { + val allStatus: ArrayList = vessel.getAllStatus() + allStatus.sortBy { (it as Status).value } + + return allStatus + } + + private fun populatLength(vessel: Vessel): ArrayList { + val allLength: ArrayList = vessel.getAllLength() + allLength.sortBy { (it as Length).value } + + return allLength + } + + private fun populatWidth(vessel: Vessel): ArrayList { + val allWidth: ArrayList = vessel.getAllWidth() + allWidth.sortBy { (it as Width).value } + + return allWidth + } + + private fun populatDraft(vessel: Vessel): ArrayList { + val allDraft: ArrayList = vessel.getAllDraft() + allDraft.sortBy { (it as Draft).value } + + return allDraft + } + + private fun populatCargo(vessel: Vessel): ArrayList { + val allCargo: ArrayList = vessel.getAllCargo() + allCargo.sortBy { (it as Cargo).value } + + return allCargo + } + + private fun populateDataList(vessel: Vessel) { + val data = arrayListOf>>() + + timeData = populateTime(vessel) + + data.add(Pair("Latitude", populateLatitude(vessel))) + + data.add(Pair("Longitude", populateLongitude(vessel))) + + data.add(Pair("Speed Over Ground", populateSpeedOverGround(vessel))) + + data.add(Pair("Course Over Ground", populateCourseOverGround(vessel))) + + data.add(Pair("Heading", populateHeading(vessel))) + + data.add(Pair("Vessel Name", populatVesselName(vessel))) + + data.add(Pair("IMO", populatIMO(vessel))) + + data.add(Pair("Call Sign", populatCallSign(vessel))) + + data.add(Pair("Vessel Type", populatVesselType(vessel))) + + data.add(Pair("Status", populatStatus(vessel))) + + data.add(Pair("Length", populatLength(vessel))) + + data.add(Pair("Width", populatWidth(vessel))) + + data.add(Pair("Draft", populatDraft(vessel))) + + data.add(Pair("Cargo", populatCargo(vessel))) + + dataList.addAll(data) + } + + override fun onValueChanged(newValue: Vessel) { + dataList.clear() + populateDataList(newValue) + + } + +} + + diff --git a/src/main/kotlin/application/controller/VesselListPanelController.kt b/src/main/kotlin/application/controller/VesselListPanelController.kt index a74069f..51726bd 100644 --- a/src/main/kotlin/application/controller/VesselListPanelController.kt +++ b/src/main/kotlin/application/controller/VesselListPanelController.kt @@ -17,7 +17,7 @@ class VesselListPanelController : Initializable, MessageListener { var shipListView: ListView = ListView() - var shipList: ObservableList = FXCollections.observableArrayList() + private var shipList: ObservableList = FXCollections.observableArrayList() override fun initialize(location: URL?, resources: ResourceBundle?) { shipListView.items = shipList diff --git a/src/main/kotlin/application/model/Message.kt b/src/main/kotlin/application/model/Message.kt index cbaeec2..8bb3bec 100644 --- a/src/main/kotlin/application/model/Message.kt +++ b/src/main/kotlin/application/model/Message.kt @@ -3,34 +3,27 @@ package application.model import java.time.LocalDateTime class Message(split: List) { - val mmsi: Int? = split[0].toIntOrNull() - val time: LocalDateTime = LocalDateTime.parse(split[1]) - val latitude: Double? = split[2].toDoubleOrNull() - val longitude: Double? = split[3].toDoubleOrNull() - val speedOverGround: Double? = split[4].toDoubleOrNull() - val courseOverGround: Double? = split[5].toDoubleOrNull() - val heading: Int? = split[6].toIntOrNull() - val vesselName: String? = split[7] - val imo: String? = split[8] - val callSign: String? = split[9] - val vesselType: Int? = split[10].toIntOrNull() - val status: String? = split[11] - val length: Double? = split[12].toDoubleOrNull() - val width: Double? = split[13].toDoubleOrNull() - val draft: Double? = split[14].toDoubleOrNull() - val cargo: Int? = split[15].toIntOrNull() + val mmsi = MMSI(split[0].toIntOrNull()) + val time = Time(LocalDateTime.parse(split[1])) + val latitude = Latitude(split[2].toDoubleOrNull()) + val longitude = Longitude(split[3].toDoubleOrNull()) + val speedOverGround = SpeedOverGround(split[4].toDoubleOrNull()) + val courseOverGround = CourseOverGround(split[5].toDoubleOrNull()) + val heading = Heading(split[6].toDoubleOrNull()) + val vesselName = VesselName(split[7]) + val imo = IMO(split[8]) + val callSign = CallSign(split[9]) + val vesselType = VesselType(split[10].toIntOrNull()) + val status = Status(split[11]) + val length = Length(split[12].toDoubleOrNull()) + val width = Width(split[13].toDoubleOrNull()) + val draft = Draft(split[14].toDoubleOrNull()) + val cargo = Cargo(split[15].toIntOrNull()) - fun getHexColorStroke(): String{ - var hex = Integer.toHexString(this.mmsi!!) - if (hex.length > 6){ - hex = hex.substring(hex.length - 6) - } - return hex - } - fun getHexColorFill(): String{ - var hex = Integer.toHexString(this.mmsi!! - 50) - if (hex.length > 6){ + fun getHexColorStroke(): String { + var hex = Integer.toHexString(this.mmsi.value!!) + if (hex.length > 6) { hex = hex.substring(hex.length - 6) } return hex diff --git a/src/main/kotlin/application/model/MessageData.kt b/src/main/kotlin/application/model/MessageData.kt new file mode 100644 index 0000000..e221950 --- /dev/null +++ b/src/main/kotlin/application/model/MessageData.kt @@ -0,0 +1,163 @@ +package application.model + +import java.time.LocalDateTime + +interface MessageDataVisitor { + fun visit(messageData: MMSI) + fun visit(messageData: Time) + fun visit(messageData: Latitude) + fun visit(messageData: Longitude) + fun visit(messageData: SpeedOverGround) + fun visit(messageData: CourseOverGround) + fun visit(messageData: Heading) + fun visit(messageData: VesselName) + fun visit(messageData: IMO) + fun visit(messageData: CallSign) + fun visit(messageData: VesselType) + fun visit(messageData: Status) + fun visit(messageData: Length) + fun visit(messageData: Width) + fun visit(messageData: Draft) + fun visit(messageData: Cargo) +} + +interface MessageData { + + fun accept(visitor: MessageDataVisitor) + +} + +data class MMSI(val value: Int?) : MessageData { + override fun accept(visitor: MessageDataVisitor) = visitor.visit(messageData = this) +} + +data class Time(val value: LocalDateTime) : MessageData { + override fun accept(visitor: MessageDataVisitor) = visitor.visit(messageData = this) +} + +data class Latitude(val value: Double?) : MessageData { + override fun accept(visitor: MessageDataVisitor) = visitor.visit(messageData = this) +} + +data class Longitude(val value: Double?) : MessageData { + override fun accept(visitor: MessageDataVisitor) = visitor.visit(messageData = this) +} + +data class SpeedOverGround(val value: Double?) : MessageData { + override fun accept(visitor: MessageDataVisitor) = visitor.visit(messageData = this) +} + +data class CourseOverGround(val value: Double?) : MessageData { + override fun accept(visitor: MessageDataVisitor) = visitor.visit(messageData = this) +} + +data class Heading(val value: Double?) : MessageData { + override fun accept(visitor: MessageDataVisitor) = visitor.visit(messageData = this) +} + +data class VesselName(val value: String?) : MessageData { + override fun accept(visitor: MessageDataVisitor) = visitor.visit(messageData = this) +} + +data class IMO(val value: String?) : MessageData { + override fun accept(visitor: MessageDataVisitor) = visitor.visit(messageData = this) +} + +data class CallSign(val value: String?) : MessageData { + override fun accept(visitor: MessageDataVisitor) = visitor.visit(messageData = this) +} + +data class VesselType(val value: Int?) : MessageData { + override fun accept(visitor: MessageDataVisitor) = visitor.visit(messageData = this) +} + +data class Status(val value: String?) : MessageData { + override fun accept(visitor: MessageDataVisitor) = visitor.visit(messageData = this) +} + +data class Length(val value: Double?) : MessageData { + override fun accept(visitor: MessageDataVisitor) = visitor.visit(messageData = this) +} + +data class Width(val value: Double?) : MessageData { + override fun accept(visitor: MessageDataVisitor) = visitor.visit(messageData = this) +} + +data class Draft(val value: Double?) : MessageData { + override fun accept(visitor: MessageDataVisitor) = visitor.visit(messageData = this) +} + +data class Cargo(val value: Int?) : MessageData { + override fun accept(visitor: MessageDataVisitor) = visitor.visit(messageData = this) +} + +class GetValueVisitor() : MessageDataVisitor { + var value: String = "" + + override fun visit(messageData: MMSI) { + value = messageData.value.toString() + } + + override fun visit(messageData: Time) { + value = messageData.value.toString() + } + + override fun visit(messageData: Latitude) { + value = messageData.value.toString() + } + + override fun visit(messageData: Longitude) { + value = messageData.value.toString() + } + + override fun visit(messageData: SpeedOverGround) { + value = messageData.value.toString() + } + + override fun visit(messageData: CourseOverGround) { + value = messageData.value.toString() + } + + override fun visit(messageData: Heading) { + value = messageData.value.toString() + } + + override fun visit(messageData: VesselName) { + value = messageData.value.toString() + } + + override fun visit(messageData: IMO) { + value = messageData.value.toString() + } + + override fun visit(messageData: CallSign) { + value = messageData.value.toString() + } + + override fun visit(messageData: VesselType) { + value = messageData.value.toString() + } + + override fun visit(messageData: Status) { + value = messageData.value.toString() + } + + override fun visit(messageData: Length) { + value = messageData.value.toString() + } + + override fun visit(messageData: Width) { + value = messageData.value.toString() + } + + override fun visit(messageData: Draft) { + value = messageData.value.toString() + } + + override fun visit(messageData: Cargo) { + value = messageData.value.toString() + } + +} + + diff --git a/src/main/kotlin/application/model/Vessel.kt b/src/main/kotlin/application/model/Vessel.kt index 9a1c30a..8e13b3f 100644 --- a/src/main/kotlin/application/model/Vessel.kt +++ b/src/main/kotlin/application/model/Vessel.kt @@ -1,9 +1,147 @@ package application.model import java.time.LocalDateTime +import java.time.ZoneOffset import java.util.* -class Vessel(val mmsi : Int?) { +class Vessel(val mmsi: Int?) { val messages: SortedMap = sortedMapOf() + + fun getAllTimeInMilliSeconde(): ArrayList { + val timeList = arrayListOf() + var timeInMilliSeconde: Long + messages.forEach { + timeInMilliSeconde = it.value.time.value.toEpochSecond(ZoneOffset.UTC).toInt().toLong() + timeList.add(timeInMilliSeconde) + } + return timeList + } + + fun getAllTime(): ArrayList { + val timeList = arrayListOf() + messages.forEach { + timeList.add(it.value.time) + } + + return timeList + } + + fun getAllLatitude(): ArrayList { + val latitudeList = arrayListOf() + messages.forEach { + latitudeList.add(it.value.latitude) + } + + return latitudeList + } + + fun getAllLongitude(): ArrayList { + val longitudeList = arrayListOf() + messages.forEach { + longitudeList.add(it.value.longitude) + } + + return longitudeList + } + + fun getAllSpeedOverGround(): ArrayList { + val speedOverGroundList = arrayListOf() + messages.forEach { + speedOverGroundList.add(it.value.speedOverGround) + } + + return speedOverGroundList + } + + fun getAllCourseOverGround(): ArrayList { + val res = arrayListOf() + messages.forEach { + res.add(it.value.courseOverGround) + } + + return res + } + + fun getAllHeading(): ArrayList { + val res = arrayListOf() + messages.forEach { + res.add(it.value.heading) + } + + return res + } + + fun getAllVesselName(): ArrayList { + val res = arrayListOf() + messages.forEach { + res.add(it.value.vesselName) + } + return res + } + + fun getAllIMO(): ArrayList { + val res = arrayListOf() + messages.forEach { + res.add(it.value.imo) + } + return res + } + + fun getAllCallSign(): ArrayList { + val res = arrayListOf() + messages.forEach { + res.add(it.value.callSign) + } + return res + } + + fun getAllVesselType(): ArrayList { + val res = arrayListOf() + messages.forEach { + res.add(it.value.vesselType) + } + return res + } + + fun getAllStatus(): ArrayList { + val res = arrayListOf() + messages.forEach { + res.add(it.value.status) + } + return res + } + + fun getAllLength(): ArrayList { + val res = arrayListOf() + messages.forEach { + res.add(it.value.length) + } + return res + } + + fun getAllWidth(): ArrayList { + val res = arrayListOf() + messages.forEach { + res.add(it.value.width) + } + return res + } + + fun getAllDraft(): ArrayList { + val res = arrayListOf() + messages.forEach { + res.add(it.value.draft) + } + return res + } + + fun getAllCargo(): ArrayList { + val res = arrayListOf() + messages.forEach { + res.add(it.value.cargo) + } + return res + } + } \ No newline at end of file diff --git a/src/main/kotlin/application/model/VesselGenerator.kt b/src/main/kotlin/application/model/VesselGenerator.kt index 7222ef6..a8a1dcb 100644 --- a/src/main/kotlin/application/model/VesselGenerator.kt +++ b/src/main/kotlin/application/model/VesselGenerator.kt @@ -13,10 +13,10 @@ fun createVesselCollection(file: File) : SortedMap { if (arrayMessage[0].toIntOrNull() !== null) { val message = Message(arrayMessage) messages.add(message) - if (!vessels.containsKey(message.mmsi)){ - vessels[message.mmsi] = Vessel(message.mmsi!!) + if (!vessels.containsKey(message.mmsi.value)){ + vessels[message.mmsi.value] = Vessel(message.mmsi.value!!) } - vessels[message.mmsi]?.messages?.set(message.time, message) + vessels[message.mmsi.value]?.messages?.set(message.time.value, message) } } diff --git a/src/main/kotlin/map/MapDisplayer.kt b/src/main/kotlin/map/MapDisplayer.kt index e1be20b..cda3bb7 100644 --- a/src/main/kotlin/map/MapDisplayer.kt +++ b/src/main/kotlin/map/MapDisplayer.kt @@ -39,7 +39,7 @@ fun displayAllMessageOnMap(map: LeafletMapView) { clearMap(map) observableVessel.vessels.forEach { (_, value) -> value.messages.forEach { (_, message) -> - map.execScript("L.circleMarker([${message.latitude}, ${message.longitude}], {renderer: myRenderer, radius: 0.01, color: '#${message.getHexColorStroke()}'}).addTo(myMap)") + map.execScript("L.circleMarker([${message.latitude.value}, ${message.longitude.value}], {renderer: myRenderer, radius: 0.01, color: '#${message.getHexColorStroke()}'}).addTo(myMap)") } } } @@ -48,10 +48,10 @@ fun displayAllMessageOnMap(map: LeafletMapView, selectedMMSI: Int) { clearMap(map) observableVessel.vessels.forEach { (_, value) -> value.messages.forEach { (_, message) -> - if (selectedMMSI == message.mmsi) { - map.execScript("L.circleMarker([${message.latitude}, ${message.longitude}], {renderer: myRenderer, radius: 2, color: '#ff4040'}).addTo(myMap)") + if (selectedMMSI == message.mmsi.value) { + map.execScript("L.circleMarker([${message.latitude.value}, ${message.longitude.value}], {renderer: myRenderer, radius: 2, color: '#ff4040'}).addTo(myMap)") } else { - map.execScript("L.circleMarker([${message.latitude}, ${message.longitude}], {renderer: myRenderer, radius: 0.01, color: '#${message.getHexColorStroke()}'}).addTo(myMap)") + map.execScript("L.circleMarker([${message.latitude.value}, ${message.longitude.value}], {renderer: myRenderer, radius: 0.01, color: '#${message.getHexColorStroke()}'}).addTo(myMap)") } } } @@ -61,7 +61,7 @@ fun displayClusterMessageOnMap(map: LeafletMapView) { clearMap(map) observableVessel.vessels.forEach { (_, value) -> value.messages.forEach { (_, message) -> - map.execScript("markerClusters.addLayer(L.circleMarker([${message.latitude}, ${message.longitude}], {renderer: myRenderer, radius: 0.01, color: '#${message.getHexColorStroke()}'}));") + map.execScript("markerClusters.addLayer(L.circleMarker([${message.latitude.value}, ${message.longitude.value}], {renderer: myRenderer, radius: 0.01, color: '#${message.getHexColorStroke()}'}));") } } map.execScript("myMap.addLayer(markerClusters);") @@ -71,10 +71,10 @@ fun displayClusterMessageOnMap(map: LeafletMapView, selectedMMSI: Int) { clearMap(map) observableVessel.vessels.forEach { (_, value) -> value.messages.forEach { (_, message) -> - if (selectedMMSI == message.mmsi) { - map.execScript("L.circleMarker([${message.latitude}, ${message.longitude}], {renderer: myRenderer, radius: 2, color: '#ff4040'}).addTo(myMap);") + if (selectedMMSI == message.mmsi.value) { + map.execScript("L.circleMarker([${message.latitude.value}, ${message.longitude.value}], {renderer: myRenderer, radius: 2, color: '#ff4040'}).addTo(myMap);") } else { - map.execScript("markerClusters.addLayer(L.circleMarker([${message.latitude}, ${message.longitude}], {renderer: myRenderer, radius: 0.01, color: '#${message.getHexColorStroke()}'}));") + map.execScript("markerClusters.addLayer(L.circleMarker([${message.latitude.value}, ${message.longitude.value}], {renderer: myRenderer, radius: 0.01, color: '#${message.getHexColorStroke()}'}));") } } } @@ -85,7 +85,7 @@ fun displayHeatMapOnMap(map: LeafletMapView) { clearMap(map) observableVessel.vessels.forEach { (_, value) -> value.messages.forEach { (_, message) -> - map.execScript("heatLayer.addLatLng([${message.latitude}, ${message.longitude}]);") + map.execScript("heatLayer.addLatLng([${message.latitude.value}, ${message.longitude.value}]);") } } } @@ -94,10 +94,10 @@ fun displayHeatMapOnMap(map: LeafletMapView, selectedMMSI: Int) { clearMap(map) observableVessel.vessels.forEach { (_, value) -> value.messages.forEach { (_, message) -> - if (selectedMMSI == message.mmsi) { - map.execScript("L.circleMarker([${message.latitude}, ${message.longitude}], {renderer: myRenderer, radius: 2, color: '#ff4040'}).addTo(myMap);") + if (selectedMMSI == message.mmsi.value) { + map.execScript("L.circleMarker([${message.latitude.value}, ${message.longitude.value}], {renderer: myRenderer, radius: 2, color: '#ff4040'}).addTo(myMap);") } else { - map.execScript("heatLayer.addLatLng([${message.latitude}, ${message.longitude}]);") + map.execScript("heatLayer.addLatLng([${message.latitude.value}, ${message.longitude.value}]);") } } } diff --git a/src/main/resources/gui/dataPanel.fxml b/src/main/resources/gui/dataPanel.fxml new file mode 100644 index 0000000..c49b85d --- /dev/null +++ b/src/main/resources/gui/dataPanel.fxml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/gui/vesselListPanel.fxml b/src/main/resources/gui/vesselListPanel.fxml index 142b074..f928dfc 100644 --- a/src/main/resources/gui/vesselListPanel.fxml +++ b/src/main/resources/gui/vesselListPanel.fxml @@ -8,7 +8,7 @@ -