diff --git a/.idea/libraries/josm_latest.xml b/.idea/libraries/josm_latest.xml new file mode 100644 index 0000000..7132779 --- /dev/null +++ b/.idea/libraries/josm_latest.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/ThoriumBusParser.iml b/ThoriumBusParser.iml index c90834f..c1fd586 100644 --- a/ThoriumBusParser.iml +++ b/ThoriumBusParser.iml @@ -7,5 +7,6 @@ + \ No newline at end of file diff --git a/josm-latest.jar b/josm-latest.jar new file mode 100644 index 0000000..47141ec Binary files /dev/null and b/josm-latest.jar differ diff --git a/src/DownloadPage.java b/src/DownloadPage.java index 0e1c055..ef7ea84 100644 --- a/src/DownloadPage.java +++ b/src/DownloadPage.java @@ -7,7 +7,7 @@ import java.net.URLConnection; public class DownloadPage { - public static String main(String inputUrl) throws IOException { + public static String DownloadPlainData(String inputUrl) throws IOException { StringBuilder pageData = new StringBuilder(); URL url = new URL(inputUrl); URLConnection con = url.openConnection(); diff --git a/src/Main.java b/src/Main.java index b1afbae..2de92f8 100644 --- a/src/Main.java +++ b/src/Main.java @@ -1,7 +1,31 @@ -import java.io.IOException; +import javax.swing.*; +import java.util.*; +import java.util.concurrent.*; public class Main { - public static void main(String[] args) throws IOException { - System.out.println(ParseGpsFile.ParseTLT(DownloadPage.main("https://transport.tallinn.ee/gps.txt"))); + public static void main(String[] args) { + List> initialData = fetchVehicleData(); + + TLTVehicleDisplayGUI gui = new TLTVehicleDisplayGUI(initialData); + SwingUtilities.invokeLater(() -> gui.setVisible(true)); + + ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor(); + executor.scheduleAtFixedRate(() -> { + List> newData = fetchVehicleData(); + SwingUtilities.invokeLater(() -> gui.refreshData(newData)); + }, 5, 5, TimeUnit.SECONDS); } -} \ No newline at end of file + + private static List> fetchVehicleData() { + List> vehicleList = new ArrayList<>(); + try { + for (String line : DownloadPage.DownloadPlainData("https://transport.tallinn.ee/gps.txt").split("\\R")) { + Map data = ParseGpsFile.ParseTLT(line); + if (data != null) vehicleList.add(data); + } + } catch (Exception e) { + // Handle exceptions silently or log + } + return vehicleList; + } +} diff --git a/src/ParseGpsFile.java b/src/ParseGpsFile.java index 7c23083..cfb2083 100644 --- a/src/ParseGpsFile.java +++ b/src/ParseGpsFile.java @@ -1,23 +1,28 @@ -import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.Map; +import java.util.Objects; public class ParseGpsFile { - public static Map ParseTLT(String GpsFileDataInput) { - String[] GpsFileDataCS = GpsFileDataInput.split(","); - - Map dataMap = new HashMap<>(); - dataMap.put("VehicleType", Double.parseDouble(GpsFileDataCS[0])); - dataMap.put("VehicleLine", Double.parseDouble(GpsFileDataCS[1])); - dataMap.put("VehicleLongitude", Double.parseDouble(GpsFileDataCS[2])); - dataMap.put("VehicleLatitude", Double.parseDouble(GpsFileDataCS[3])); - dataMap.put("EmptyVal1", Double.parseDouble(GpsFileDataCS[4])); - dataMap.put("VehicleHeading", Double.parseDouble(GpsFileDataCS[5])); - dataMap.put("VehicleTAK", Double.parseDouble(GpsFileDataCS[6])); - dataMap.put("IsVehicleLowGroundVehicle", Double.parseDouble(GpsFileDataCS[7])); - dataMap.put("EmptyVal2", Double.parseDouble(GpsFileDataCS[8])); - dataMap.put("VehicleDestination", Double.parseDouble(GpsFileDataCS[9])); + public static Map ParseTLT(String GpsFileDataInput) { + String[] GpsFileDataCS = GpsFileDataInput.split(","); // GpsFileDataC(omma)S(eparated) + Map dataMap = new LinkedHashMap<>(); + dataMap.put("VehicleType", GpsFileDataCS[0]); + dataMap.put("VehicleLine", GpsFileDataCS[1]); + dataMap.put("VehicleLatitude", GpsFileDataCS[3]); + dataMap.put("VehicleLongitude", GpsFileDataCS[2]); + dataMap.put("VehicleHeading", GpsFileDataCS[5]); + dataMap.put("VehicleTAK", GpsFileDataCS[6]); + String val = GpsFileDataCS[7].toLowerCase(); // + String isLowGround; // + if (Objects.equals(val, "z")) { // + isLowGround = "true"; // Parse from the stupid z=true,false=false system + } else { // TLT uses to true=true,false=false system. + isLowGround = "false"; // + } // + dataMap.put("IsVehicleLowGroundVehicle", isLowGround); + dataMap.put("VehicleDestination", GpsFileDataCS[9]); return dataMap; } } \ No newline at end of file diff --git a/src/TLTVehicleDisplayGUI.java b/src/TLTVehicleDisplayGUI.java new file mode 100644 index 0000000..d6f02d6 --- /dev/null +++ b/src/TLTVehicleDisplayGUI.java @@ -0,0 +1,99 @@ +import javax.swing.*; +import javax.swing.table.DefaultTableModel; +import java.awt.*; +import java.awt.event.*; +import java.util.List; +import java.util.Map; +import org.openstreetmap.gui.jmapviewer.*; + +public class TLTVehicleDisplayGUI extends JFrame { + private DefaultTableModel model; + private JTable table; + private JMapViewer map; + private List> vehicles; + + public TLTVehicleDisplayGUI(List> initialVehicles) { + this.vehicles = initialVehicles; + + setTitle("ThoriumBusParser v1.0 - (c) 2025 VELENDEU, eetnaviation"); + setDefaultCloseOperation(EXIT_ON_CLOSE); + setSize(900, 600); + setLayout(new BorderLayout()); + + String[] columns = {"Type", "Line", "Latitude", "Longitude", + "Heading", "TAK", "IsLowGround", "Destination"}; + model = new DefaultTableModel(columns, 0); + table = new JTable(model); + JScrollPane tableScroll = new JScrollPane(table); + + map = new JMapViewer(); + + JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, tableScroll, map); + splitPane.setDividerLocation(400); + add(splitPane, BorderLayout.CENTER); + + table.getSelectionModel().addListSelectionListener(e -> { + if (!e.getValueIsAdjusting()) { + int index = table.getSelectedRow(); + if (index >= 0 && index < map.getMapMarkerList().size()) { + MapMarkerDot marker = (MapMarkerDot) map.getMapMarkerList().get(index); + map.setDisplayPosition(marker.getCoordinate(), 15); + } + } + }); + + map.addMouseListener(new java.awt.event.MouseAdapter() { + @Override + public void mouseClicked(java.awt.event.MouseEvent e) { + Point clickPoint = e.getPoint(); + for (int i = 0; i < map.getMapMarkerList().size(); i++) { + MapMarkerDot marker = (MapMarkerDot) map.getMapMarkerList().get(i); + Point markerPos = map.getMapPosition(marker.getCoordinate(), false); + if (markerPos != null && clickPoint.distance(markerPos) <= 10) { + table.setRowSelectionInterval(i, i); + table.scrollRectToVisible(table.getCellRect(i, 0, true)); + break; + } + } + } + }); + + refreshData(vehicles); + } + + public void refreshData(List> newVehicles) { + this.vehicles = newVehicles; + model.setRowCount(0); + map.removeAllMapMarkers(); + + for (Map vehicle : vehicles) { + String typeStr = vehicle.get("VehicleType"); + String typeText = switch (typeStr) { + case "1" -> "Trolleybus"; + case "2" -> "Bus"; + case "3" -> "Tram"; + case "7" -> "Nightbus"; + default -> "Unknown"; + }; + + double lat = Integer.parseInt(vehicle.get("VehicleLatitude")) / 1_000_000.0; + double lon = Integer.parseInt(vehicle.get("VehicleLongitude")) / 1_000_000.0; + + Object[] row = { + typeText, + vehicle.get("VehicleLine"), + lat, + lon, + vehicle.get("VehicleHeading"), + vehicle.get("VehicleTAK"), + vehicle.get("IsVehicleLowGroundVehicle"), + vehicle.get("VehicleDestination") + }; + model.addRow(row); + + MapMarkerDot marker = new MapMarkerDot(lat, lon); + marker.setName(typeText + " " + vehicle.get("VehicleLine")); + map.addMapMarker(marker); + } + } +}