Commit 52321443a825ac8fb03d327344e14db4da305d0a
1 parent
43370abfea
Exists in
master
and in
1 other branch
different color for different boat + JMetro
Showing 6 changed files with 24 additions and 22 deletions Inline Diff
build.gradle
View file @
5232144
| plugins { | 1 | 1 | plugins { | |
| id 'java' | 2 | 2 | id 'java' | |
| id 'org.jetbrains.kotlin.jvm' version '1.3.72' | 3 | 3 | id 'org.jetbrains.kotlin.jvm' version '1.3.72' | |
| } | 4 | 4 | } | |
| 5 | 5 | |||
| group 'marivisu' | 6 | 6 | group 'marivisu' | |
| version '1.0-SNAPSHOT' | 7 | 7 | version '1.0-SNAPSHOT' | |
| 8 | 8 | |||
| repositories { | 9 | 9 | repositories { | |
| mavenCentral() | 10 | 10 | mavenCentral() | |
| } | 11 | 11 | } | |
| 12 | 12 | |||
| dependencies { | 13 | 13 | dependencies { | |
| implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8" | 14 | 14 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8" | |
| 15 | implementation 'org.jfxtras:jmetro:8.6.9' | |||
| testCompile group: 'junit', name: 'junit', version: '4.12' | 15 | 16 | testCompile group: 'junit', name: 'junit', version: '4.12' | |
| } | 16 | 17 | } | |
| 17 | 18 | |||
| compileKotlin { | 18 | 19 | compileKotlin { | |
| kotlinOptions.jvmTarget = "1.8" | 19 | 20 | kotlinOptions.jvmTarget = "1.8" |
src/main/kotlin/application/App.kt
View file @
5232144
| package application | 1 | 1 | package application | |
| 2 | 2 | |||
| import javafx.application.Application | 3 | 3 | import javafx.application.Application | |
| import javafx.fxml.FXMLLoader | 4 | 4 | import javafx.fxml.FXMLLoader | |
| import javafx.scene.Parent | 5 | 5 | import javafx.scene.Parent | |
| import javafx.scene.Scene | 6 | 6 | import javafx.scene.Scene | |
| import javafx.stage.Stage | 7 | 7 | import javafx.stage.Stage | |
| 8 | import jfxtras.styles.jmetro.JMetro | |||
| 9 | import jfxtras.styles.jmetro.Style | |||
| 8 | 10 | |||
| class App : Application() { | 9 | 11 | class App : Application() { | |
| 12 | var style : Style = Style.LIGHT | |||
| 10 | 13 | |||
| 11 | ||||
| override fun start(primaryStage: Stage?) { | 12 | 14 | override fun start(primaryStage: Stage?) { | |
| 13 | 15 | |||
| 14 | ||||
| 15 | ||||
| val fxmlLoader = FXMLLoader(App::class.java.getResource("/gui/windows.fxml")) | 16 | 16 | val fxmlLoader = FXMLLoader(App::class.java.getResource("/gui/windows.fxml")) | |
| val parent: Parent = fxmlLoader.load() | 17 | 17 | val parent: Parent = fxmlLoader.load() | |
| val scene = Scene(parent) | 18 | 18 | val scene = Scene(parent) | |
| 19 | 19 | JMetro(scene, style) | ||
| primaryStage!!.scene = scene | 20 | 20 | primaryStage!!.scene = scene | |
| primaryStage.title = "Maritime Visualisation" | 21 | 21 | primaryStage.title = "Maritime Visualisation" | |
| primaryStage.show() | 22 | 22 | primaryStage.show() | |
| } | 23 | 23 | } |
src/main/kotlin/application/model/Message.kt
View file @
5232144
| package application.model | 1 | 1 | package application.model | |
| 2 | 2 | |||
| import java.time.LocalDateTime | 3 | 3 | import java.time.LocalDateTime | |
| 4 | 4 | |||
| class Message(split: List<String>) { | 5 | 5 | class Message(split: List<String>) { | |
| val mmsi: Int? = split[0].toIntOrNull() | 6 | 6 | val mmsi: Int? = split[0].toIntOrNull() | |
| val time: LocalDateTime = LocalDateTime.parse(split[1]) | 7 | 7 | val time: LocalDateTime = LocalDateTime.parse(split[1]) | |
| val latitude: Double? = split[2].toDoubleOrNull() | 8 | 8 | val latitude: Double? = split[2].toDoubleOrNull() | |
| val longitude: Double? = split[3].toDoubleOrNull() | 9 | 9 | val longitude: Double? = split[3].toDoubleOrNull() | |
| val speedOverGround: Double? = split[4].toDoubleOrNull() | 10 | 10 | val speedOverGround: Double? = split[4].toDoubleOrNull() | |
| val courseOverGround: Double? = split[5].toDoubleOrNull() | 11 | 11 | val courseOverGround: Double? = split[5].toDoubleOrNull() | |
| val heading: Int? = split[6].toIntOrNull() | 12 | 12 | val heading: Int? = split[6].toIntOrNull() | |
| val vesselName: String? = split[7] | 13 | 13 | val vesselName: String? = split[7] | |
| val imo: String? = split[8] | 14 | 14 | val imo: String? = split[8] | |
| val callSign: String? = split[9] | 15 | 15 | val callSign: String? = split[9] | |
| val vesselType: Int? = split[10].toIntOrNull() | 16 | 16 | val vesselType: Int? = split[10].toIntOrNull() | |
| val status: String? = split[11] | 17 | 17 | val status: String? = split[11] | |
| val length: Double? = split[12].toDoubleOrNull() | 18 | 18 | val length: Double? = split[12].toDoubleOrNull() | |
| val width: Double? = split[13].toDoubleOrNull() | 19 | 19 | val width: Double? = split[13].toDoubleOrNull() | |
| val draft: Double? = split[14].toDoubleOrNull() | 20 | 20 | val draft: Double? = split[14].toDoubleOrNull() | |
| val cargo: Int? = split[15].toIntOrNull() | 21 | 21 | val cargo: Int? = split[15].toIntOrNull() | |
| 22 | 22 | |||
| 23 | fun getHexColor(): String{ | |||
| 24 | var hex = Integer.toHexString(this.mmsi!!) | |||
| 25 | if (hex.length > 6){ | |||
| 26 | hex = hex.substring(hex.length - 6) | |||
| 27 | } |
src/main/kotlin/application/model/ObservableVessel.kt
View file @
5232144
| package application.model | 1 | 1 | package application.model | |
| 2 | 2 | |||
| import java.util.* | 3 | |||
| import kotlin.properties.Delegates | 4 | 3 | import kotlin.properties.Delegates | |
| 5 | 4 | |||
| class ObservableVessel { | 6 | 5 | class ObservableVessel { | |
| val listeners: MutableList<MessageListener> = mutableListOf() | 7 | 6 | val listeners: MutableList<MessageListener> = mutableListOf() | |
| 8 | 7 | |||
| var vessels: MutableMap<Int?, Vessel> by Delegates.observable( | 9 | 8 | var vessels: MutableMap<Int?, Vessel> by Delegates.observable( | |
| initialValue = mutableMapOf(), | 10 | 9 | initialValue = mutableMapOf(), | |
| onChange = { | 11 | 10 | onChange = { _, _, new -> | |
| _, _, new -> | 12 | |||
| run { | 13 | 11 | run { | |
| listeners.forEach { | 14 | 12 | listeners.forEach { | |
| it.onValueChanged(new) | 15 | 13 | it.onValueChanged(new) | |
| } | 16 | 14 | } | |
| } | 17 | 15 | } | |
| } | 18 | 16 | } |
src/main/kotlin/map/CircleMarkerGenerator.kt
View file @
5232144
| package map | 1 | 1 | package map | |
| 2 | 2 | |||
| import application.model.observableMessages | 3 | 3 | import application.model.observableMessages | |
| 4 | 4 | |||
| fun clearMapCanvas(map: LeafletMapView) { | 5 | 5 | fun clearMapCanvas(map: LeafletMapView) { | |
| map.execScript(""" | 6 | 6 | map.execScript(""" | |
| |myRenderer.removeFrom(myMap) | 7 | 7 | |myRenderer.removeFrom(myMap) | |
| |var myRenderer = L.canvas({ padding: 0.5 }); | 8 | 8 | |var myRenderer = L.canvas({ padding: 0.5 }); | |
| """.trimMargin()) | 9 | 9 | """.trimMargin()) | |
| } | 10 | 10 | } | |
| 11 | 11 | |||
| fun displayMessageOnMap(map: LeafletMapView) { | 12 | 12 | fun displayMessageOnMap(map: LeafletMapView) { | |
| clearMapCanvas(map) | 13 | 13 | clearMapCanvas(map) | |
| observableMessages.vessels.forEach { (_, value) -> | 14 | 14 | observableMessages.vessels.forEach { (_, value) -> | |
| value.messages.forEach { (_, message) -> | 15 | 15 | value.messages.forEach { (_, message) -> | |
| map.execScript("L.circleMarker([${message.latitude}, ${message.longitude}], {renderer: myRenderer, radius: 0.01}).addTo(myMap)") | 16 | 16 | map.execScript("L.circleMarker([${message.latitude}, ${message.longitude}], {renderer: myRenderer, radius: 0.01, color: '#${message.getHexColor()}'}).addTo(myMap)") | |
| } | 17 | 17 | } |
src/main/resources/gui/windows.fxml
View file @
5232144
| <?xml version="1.0" encoding="UTF-8"?> | 1 | 1 | <?xml version="1.0" encoding="UTF-8"?> | |
| 2 | 2 | |||
| <?import javafx.scene.control.SplitPane?> | 3 | 3 | <?import javafx.scene.control.*?> | |
| <?import javafx.scene.layout.*?> | 4 | 4 | <?import javafx.scene.layout.*?> | |
| <AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="900.0" | 5 | 5 | <?import javafx.scene.shape.*?> | |
| prefWidth="1200.0" xmlns="http://javafx.com/javafx/10.0.2-internal" xmlns:fx="http://javafx.com/fxml/1"> | 6 | 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"> | |||
| <children> | 7 | 8 | <children> | |
| <fx:include source="menuBar.fxml" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" | 8 | 9 | <fx:include source="menuBar.fxml" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" /> | |
| AnchorPane.topAnchor="0.0"/> | 9 | 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"> | |
| <SplitPane dividerPositions="0.29797979797979796" layoutY="25.0" prefHeight="379.0" prefWidth="594.0" | 10 | |||
| AnchorPane.bottomAnchor="-4.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="6.0" | 11 | |||
| AnchorPane.topAnchor="25.0"> | 12 | |||
| <items> | 13 | 11 | <items> | |
| <AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="160.0" prefWidth="100.0"> | 14 | 12 | <AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="160.0" prefWidth="100.0"> | |
| <children> | 15 | 13 | <children> | |
| <fx:include source="controlPanel.fxml" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" | 16 | 14 | <fx:include source="controlPanel.fxml" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" /> | |
| AnchorPane.topAnchor="0.0"/> | 17 | |||
| </children> | 18 | 15 | </children> | |
| </AnchorPane> | 19 | 16 | </AnchorPane> | |
| <AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="160.0" prefWidth="100.0"> | 20 | 17 | <AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="160.0" prefWidth="100.0"> | |
| <children> | 21 | 18 | <children> | |
| <SplitPane dividerPositions="0.536" layoutX="127.0" layoutY="74.0" orientation="VERTICAL" | 22 | 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"> | |
| prefHeight="200.0" prefWidth="160.0" AnchorPane.bottomAnchor="0.0" | 23 | |||
| AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0"> | 24 | |||
| <items> | 25 | 20 | <items> | |
| <fx:include source="mapPanel.fxml" /> | 26 | 21 | <fx:include source="mapPanel.fxml" /> | |
| <AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="100.0" prefWidth="160.0"/> | 27 | 22 | <AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="100.0" prefWidth="160.0" /> | |
| </items> | 28 | 23 | </items> | |
| </SplitPane> | 29 | 24 | </SplitPane> | |
| </children> | 30 | 25 | </children> | |
| </AnchorPane> | 31 | 26 | </AnchorPane> | |
| </items> | 32 | 27 | </items> | |
| </SplitPane> | 33 | 28 | </SplitPane> | |
| 29 | <Line endX="1101.0" endY="1.1444091796875E-5" layoutX="101.0" layoutY="35.0" startX="-100.0" /> | |||
| </children> | 34 | 30 | </children> | |
| </AnchorPane> | 35 | 31 | </AnchorPane> | |
| 36 | 32 | |||