Commit 513c0341c54e1d2ef6dbd1eeb624830faab35ad7
1 parent
07bf03cd80
Exists in
master
and in
1 other branch
add chart
Showing 11 changed files with 670 additions and 55 deletions Side-by-side Diff
- src/main/kotlin/application/VisualisationChart.kt
- src/main/kotlin/application/controller/DataPanelController.kt
- src/main/kotlin/application/controller/VesselListPanelController.kt
- src/main/kotlin/application/model/Message.kt
- src/main/kotlin/application/model/MessageData.kt
- src/main/kotlin/application/model/Vessel.kt
- src/main/kotlin/application/model/VesselGenerator.kt
- src/main/kotlin/map/MapDisplayer.kt
- src/main/resources/gui/dataPanel.fxml
- src/main/resources/gui/vesselListPanel.fxml
- src/main/resources/gui/windows.fxml
src/main/kotlin/application/VisualisationChart.kt
View file @
513c034
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> |