From 458d31f2c4cbdadbecd7520a5fdc24b66ff8242a Mon Sep 17 00:00:00 2001 From: Francois Date: Sat, 4 May 2024 20:37:38 +0200 Subject: [PATCH 1/5] Some algorithm optimizations --- .../gla/project/idfm/CSVStreamProvider.java | 2 +- .../u_paris/gla/project/itinerary/Connection.java | 2 +- .../fr/u_paris/gla/project/itinerary/Finder.java | 7 ++++++- .../fr/u_paris/gla/project/itinerary/Graph.java | 15 +++++++++++++++ .../fr/u_paris/gla/project/itinerary/Stop.java | 8 +++++++- 5 files changed, 30 insertions(+), 4 deletions(-) diff --git a/src/main/java/fr/u_paris/gla/project/idfm/CSVStreamProvider.java b/src/main/java/fr/u_paris/gla/project/idfm/CSVStreamProvider.java index fe8133f..f31339d 100644 --- a/src/main/java/fr/u_paris/gla/project/idfm/CSVStreamProvider.java +++ b/src/main/java/fr/u_paris/gla/project/idfm/CSVStreamProvider.java @@ -271,7 +271,7 @@ public final class CSVStreamProvider { Double max_speed = max_speed_by_type.get(type); Double two_acc_distance = two_acceleration_distance_by_type.get(type); return Math.max(0, distance - two_acc_distance) / max_speed - + Math.pow(Math.min(distance, two_acc_distance) / max_speed, 2); + + 2 * Math.sqrt(Math.min(distance, two_acc_distance) * two_acc_distance)/max_speed; } private void fillTransports(int bif) { diff --git a/src/main/java/fr/u_paris/gla/project/itinerary/Connection.java b/src/main/java/fr/u_paris/gla/project/itinerary/Connection.java index c9b8608..c1eb1d3 100644 --- a/src/main/java/fr/u_paris/gla/project/itinerary/Connection.java +++ b/src/main/java/fr/u_paris/gla/project/itinerary/Connection.java @@ -87,7 +87,7 @@ public class Connection{ public double getCost(double currentTime) { if(this.schedules.size() == 0) { - if(this.lineName.equals("WALK")) { + if(this.lineName.equals("WALK") || this.lineName.equals("")) { return this.time; } return this.time + 900; diff --git a/src/main/java/fr/u_paris/gla/project/itinerary/Finder.java b/src/main/java/fr/u_paris/gla/project/itinerary/Finder.java index 2cd8bba..1d469f6 100644 --- a/src/main/java/fr/u_paris/gla/project/itinerary/Finder.java +++ b/src/main/java/fr/u_paris/gla/project/itinerary/Finder.java @@ -27,7 +27,12 @@ public class Finder { graph.addNode(fromNode); graph.addNode(toNode); - return findPath(fromNode, toNode, startTime); + List result = findPath(fromNode, toNode, startTime); + + graph.removeNode(fromNode); + graph.removeNode(toNode); + + return result; } /** diff --git a/src/main/java/fr/u_paris/gla/project/itinerary/Graph.java b/src/main/java/fr/u_paris/gla/project/itinerary/Graph.java index 76af8dd..a8919eb 100644 --- a/src/main/java/fr/u_paris/gla/project/itinerary/Graph.java +++ b/src/main/java/fr/u_paris/gla/project/itinerary/Graph.java @@ -1,5 +1,6 @@ package fr.u_paris.gla.project.itinerary; +import java.util.ArrayList; import java.util.HashSet; import java.util.Map; import java.util.Set; @@ -43,6 +44,20 @@ public class Graph { } public void removeNode(Stop s) { + for(Stop stop : nodes) { + if(getConnections(stop) == null) { + continue; + } + ArrayList toRemove = new ArrayList<>(); + for(Connection c : getConnections(stop)) { + if(c.getStop() == s) { + toRemove.add(c); + } + } + for(Connection c : toRemove) { + getConnections(stop).remove(c); + } + } nodes.remove(s); connections.remove(s); } diff --git a/src/main/java/fr/u_paris/gla/project/itinerary/Stop.java b/src/main/java/fr/u_paris/gla/project/itinerary/Stop.java index c814f37..0305d79 100644 --- a/src/main/java/fr/u_paris/gla/project/itinerary/Stop.java +++ b/src/main/java/fr/u_paris/gla/project/itinerary/Stop.java @@ -1,5 +1,7 @@ package fr.u_paris.gla.project.itinerary; +import fr.u_paris.gla.project.utils.GPS; + import java.util.HashSet; import java.util.Set; @@ -20,6 +22,9 @@ public class Stop { private double f; + //Maximal speed in m/s + private final double MAX_SPEED = 14.; + public Stop(String line, String name, double latitude, double longitude) { lines = new HashSet<>(); lines.add(line); @@ -40,7 +45,8 @@ public class Stop { } public double getHeuristicCost(Stop goalNode) { - return 0; + double distance = GPS.distance(this.latitude, this.longitude, goalNode.latitude, goalNode.longitude); + return distance/MAX_SPEED; } public Set getNeighbors() { From 9716f3e64dd26382c9e91f4af1dde7df0d63935c Mon Sep 17 00:00:00 2001 From: Mylloon Date: Sun, 5 May 2024 12:21:15 +0200 Subject: [PATCH 2/5] [chore] ignore generated files --- .gitignore | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 3d6d6b3..2eec579 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,10 @@ # Maven target/ -# Files -.csv +# Generated files +hours.csv +images.csv +trace.csv # IDEs # Eclipse From 6ecff939efb75d23363f0f6befefec455dc45ceb Mon Sep 17 00:00:00 2001 From: Lucas Date: Sun, 5 May 2024 11:47:41 +0200 Subject: [PATCH 3/5] [test] Fix non working test --- .../gla/project/idfm/CSVStreamProviderTest.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/test/java/fr/u_paris/gla/project/idfm/CSVStreamProviderTest.java b/src/test/java/fr/u_paris/gla/project/idfm/CSVStreamProviderTest.java index d447be9..3e912fe 100644 --- a/src/test/java/fr/u_paris/gla/project/idfm/CSVStreamProviderTest.java +++ b/src/test/java/fr/u_paris/gla/project/idfm/CSVStreamProviderTest.java @@ -99,22 +99,22 @@ public class CSVStreamProviderTest { @Test public void testDistanceToTime() throws Exception { // Valeurs fictives pour TWO_ACCELERATION_DISTANCE et MAX_SPEED - final double TWO_ACCELERATION_DISTANCE = 0.1; // Par exemple - final double MAX_SPEED = 10.0; // Par exemple + final double TWO_ACCELERATION_DISTANCE = 0.1; + final double MAX_SPEED = 10.0; // Exemple de distance à tester double distanceExample = 1.0; // 1 km // Calcul attendu basé sur la formule fournie double expected = Math.max(0, distanceExample - TWO_ACCELERATION_DISTANCE) / MAX_SPEED - + Math.pow(Math.min(distanceExample, TWO_ACCELERATION_DISTANCE) / MAX_SPEED, 2); + + (2 * Math.sqrt(Math.min(distanceExample, TWO_ACCELERATION_DISTANCE) * TWO_ACCELERATION_DISTANCE) / MAX_SPEED); // Accès à la méthode distanceToTime via la réflexion - Method method = CSVStreamProvider.class.getDeclaredMethod("distanceToTime", double.class,String.class); + Method method = CSVStreamProvider.class.getDeclaredMethod("distanceToTime", double.class, String.class); method.setAccessible(true); // Invocation de la méthode distanceToTime et stockage du résultat - double result = (Double) method.invoke(null, distanceExample,"Bus"); + double result = (Double) method.invoke(null, distanceExample, "Bus"); // Assertion pour vérifier si le résultat est conforme à l'attendu assertEquals(expected, result, "Le calcul du temps à partir de la distance devrait être conforme à l'attendu."); From f764a80882da24935637e29fa19f48d1541a7f18 Mon Sep 17 00:00:00 2001 From: Lucas Date: Sun, 5 May 2024 12:13:06 +0200 Subject: [PATCH 4/5] [docs] Some comments, code cleanup et README update --- README.md | 21 ++++++++----------- src/main/java/fr/u_paris/gla/project/App.java | 21 ------------------- .../gla/project/idfm/CSVImageProvider.java | 10 +++++---- .../project/idfm/CSVSchedulesProvider.java | 2 +- .../gla/project/idfm/CSVStreamProvider.java | 2 +- .../u_paris/gla/project/idfm/ImagePair.java | 11 ++++++++++ .../u_paris/gla/project/io/ImageFormat.java | 5 ----- .../u_paris/gla/project/utils/ApiUtils.java | 10 ++++++++- .../u_paris/gla/project/utils/CSVTools.java | 16 -------------- 9 files changed, 37 insertions(+), 61 deletions(-) diff --git a/README.md b/README.md index 51a3cee..1c67b92 100644 --- a/README.md +++ b/README.md @@ -18,31 +18,28 @@ Afin de compiler et lancer les tests, exécutez simplement mvn verify ``` -Afin de vérifier les tests via JaCoCo. -Les résultats du test sont dans `target/site/jacoco/index.html`. - -```bash -mvn clean jacoco:prepare-agent install jacoco:report -``` - -Par la suite, `mvn jacoco:report` suffit. - Dans sa version initiale, le programme fournit est un simple code qui se lance en terminal ou en application graphique. Une fois le programme compilé, vous trouverez un jar executable dans le dossier target. Au nom de jar près (version changeante), vous pourrez l'exécuter avec: ``` -java -jar target/project-2024.1.0.0-SNAPSHOT.jar --info +java -jar target/project-2024.1.0.0-SNAPSHOT.jar ``` L'option de lancement `--info` causera l'affichage dans la console d'informations de l'application. L'option de lancement `--gui` causera l'ouverture d'une fenêtre affichant le logo de l'Université de Paris. +Sans option, le programme Pathfinder sera lancé. + ## Tests JaCoCo -``` +Afin de vérifier la couverture des tests via JaCoCo: + +```bash mvn clean jacoco:prepare-agent install jacoco:report ``` -Puis ouvrir le fichier `./target/site/jacoco/index.html`. +Les résultats seront stockés dans `target/site/jacoco/index.html`. + +Par la suite, ```mvn jacoco:report``` suffit. diff --git a/src/main/java/fr/u_paris/gla/project/App.java b/src/main/java/fr/u_paris/gla/project/App.java index 043ad3e..357df3e 100644 --- a/src/main/java/fr/u_paris/gla/project/App.java +++ b/src/main/java/fr/u_paris/gla/project/App.java @@ -64,7 +64,6 @@ public class App { } } else { - // testRelease(); run(); } } @@ -83,26 +82,6 @@ public class App { SwingUtilities.invokeLater(() -> new View(graph, finder, s)); } - public static void testRelease(){ - Parse parse = new Parse(); - parse.parseFiles(); - Stop source = parse.getTmp().get("Porte d'Ivry").get(0); - Stop destination = parse.getTmp().get("Châtelet").get(0); - System.out.println("Itinéraire de Porte d'Ivry à Châtelet"); - List result = parse.getItinerary(source, destination, 43200); - for(Path element : result){ - System.out.println(element.getCurrentStop()); - } - System.out.println("°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°"); - System.out.println("Itinéraire de Porte d'Ivry à Châtelet"); - source = parse.getTmp().get("Saint-Jacques").get(0); - destination = parse.getTmp().get("Porte d'Ivry").get(0); - result = parse.getItinerary(source, destination, 43200); - for(Path element : result){ - System.out.println(element.getCurrentStop()); - } - - } /** @param out the output stream */ public static void printAppInfos(PrintStream out) { Properties props = readApplicationProperties(); diff --git a/src/main/java/fr/u_paris/gla/project/idfm/CSVImageProvider.java b/src/main/java/fr/u_paris/gla/project/idfm/CSVImageProvider.java index 04341ee..bd91c79 100644 --- a/src/main/java/fr/u_paris/gla/project/idfm/CSVImageProvider.java +++ b/src/main/java/fr/u_paris/gla/project/idfm/CSVImageProvider.java @@ -60,6 +60,12 @@ public final class CSVImageProvider { return Arrays.copyOf(this.line, this.line.length); } + /** + * This function returns a list of ImagePair, which represents the name of the line and the link to the + * image of the line details. + * The list is created once and then store in a static variable. + * @return an ArrayList of ImagePair + */ public static ArrayList getLineImageMap() { if (lineImageMap != null) return lineImageMap; @@ -72,10 +78,6 @@ public final class CSVImageProvider { String detail = line[ImageFormat.LINE_DETAIL_INDEX]; String imageUrl = line[ImageFormat.IMAGE_URL_INDEX]; - int index = (int) lineImageMap.stream() - .filter(pair -> pair.getLine().equals(label)) - .count(); - lineImageMap.add(new ImagePair(label, detail, imageUrl)); }); } diff --git a/src/main/java/fr/u_paris/gla/project/idfm/CSVSchedulesProvider.java b/src/main/java/fr/u_paris/gla/project/idfm/CSVSchedulesProvider.java index 4f993ce..e700f8b 100644 --- a/src/main/java/fr/u_paris/gla/project/idfm/CSVSchedulesProvider.java +++ b/src/main/java/fr/u_paris/gla/project/idfm/CSVSchedulesProvider.java @@ -71,7 +71,7 @@ public class CSVSchedulesProvider { } /** - * Move to the the nextDescription of a Transport line + * Move to the nextDescription of a Transport line */ private void skipToNextDescription() { if (this.currentDescription.hasNext()) { diff --git a/src/main/java/fr/u_paris/gla/project/idfm/CSVStreamProvider.java b/src/main/java/fr/u_paris/gla/project/idfm/CSVStreamProvider.java index f31339d..068ee68 100644 --- a/src/main/java/fr/u_paris/gla/project/idfm/CSVStreamProvider.java +++ b/src/main/java/fr/u_paris/gla/project/idfm/CSVStreamProvider.java @@ -202,7 +202,7 @@ public final class CSVStreamProvider { } while (currentSegmentStart == null); } - /** Store current trace' data as a String array + /** Store current trace data as a String array * @return The newly generated line of text */ public String[] next() { diff --git a/src/main/java/fr/u_paris/gla/project/idfm/ImagePair.java b/src/main/java/fr/u_paris/gla/project/idfm/ImagePair.java index 90d7d01..8ecc562 100644 --- a/src/main/java/fr/u_paris/gla/project/idfm/ImagePair.java +++ b/src/main/java/fr/u_paris/gla/project/idfm/ImagePair.java @@ -5,8 +5,19 @@ package fr.u_paris.gla.project.idfm; * These getters ables a ComboBox to show the label returned by toString, and get a specific value when the object is returned */ public class ImagePair { + /** + * The name of the line + */ private final String line; + + /** + * The label that will be shown in the ComboBox + */ private final String label; + + /** + * The link of the line details + */ private final String value; public ImagePair(String label, String label_detail, String value){ diff --git a/src/main/java/fr/u_paris/gla/project/io/ImageFormat.java b/src/main/java/fr/u_paris/gla/project/io/ImageFormat.java index e10a671..ca53199 100644 --- a/src/main/java/fr/u_paris/gla/project/io/ImageFormat.java +++ b/src/main/java/fr/u_paris/gla/project/io/ImageFormat.java @@ -3,11 +3,6 @@ */ package fr.u_paris.gla.project.io; -import java.time.format.DateTimeFormatter; -import java.time.format.ResolverStyle; -import java.util.ArrayList; -import java.util.List; - /** * A tool class for the Image format. */ diff --git a/src/main/java/fr/u_paris/gla/project/utils/ApiUtils.java b/src/main/java/fr/u_paris/gla/project/utils/ApiUtils.java index 3a40845..bc5f24e 100644 --- a/src/main/java/fr/u_paris/gla/project/utils/ApiUtils.java +++ b/src/main/java/fr/u_paris/gla/project/utils/ApiUtils.java @@ -17,9 +17,17 @@ public class ApiUtils { private static final Logger LOGGER = Logger .getLogger(IDFMNetworkExtractor.class.getName()); - // OpenStreetMap API URL + /** + * OpenStreetMap API URL + */ private static final String OSM_URL = "https://nominatim.openstreetmap.org/search"; + /** + * This function returns the GPS location of a string, using OSM API. + * The string can be anything, and adress, a street, a place. + * @param term the term to search + * @return the GPS location, (0,0) if not result + */ public static double[] getGPSLocation(String term) { try { String urlString = String.format("%s?q=%s&format=json", OSM_URL, URLEncoder.encode(term, StandardCharsets.UTF_8)); diff --git a/src/main/java/fr/u_paris/gla/project/utils/CSVTools.java b/src/main/java/fr/u_paris/gla/project/utils/CSVTools.java index 6b51854..c9a1fd8 100644 --- a/src/main/java/fr/u_paris/gla/project/utils/CSVTools.java +++ b/src/main/java/fr/u_paris/gla/project/utils/CSVTools.java @@ -87,20 +87,4 @@ public final class CSVTools { } } } - - // /** Save our current CSV variable's data into an actual file - // * @param filename the saved file's name and path - // * @param contentLineConsumer our data variable - // * @throws IOException if we can't write the data into the file - // */ - // public static void writeCSVToFile(String filename, - // Stream contentLinesConsumer) throws IOException { - // try (FileWriter writer = new FileWriter(filename, StandardCharsets.UTF_8)) { - // CSVWriterBuilder wBuilder = new CSVWriterBuilder(writer).withSeparator(';'); - // try (ICSVWriter csv = wBuilder.build()) { - // contentLinesConsumer.forEachOrdered(line -> Arrays.stream(line).forEach(csv::writeNext)); - // } - // } - // } - } From 0c20cd68402c90697d106e6a1e06182220f58b88 Mon Sep 17 00:00:00 2001 From: Lucas Date: Sun, 5 May 2024 12:32:44 +0200 Subject: [PATCH 5/5] [fix] Fix crash with empty string, remove some prints --- .../java/fr/u_paris/gla/project/gui/View.java | 79 ++++--------------- 1 file changed, 14 insertions(+), 65 deletions(-) diff --git a/src/main/java/fr/u_paris/gla/project/gui/View.java b/src/main/java/fr/u_paris/gla/project/gui/View.java index 6ed68bf..0c89a9a 100644 --- a/src/main/java/fr/u_paris/gla/project/gui/View.java +++ b/src/main/java/fr/u_paris/gla/project/gui/View.java @@ -290,6 +290,7 @@ public class View extends JFrame { }); } }); + SeeStopButton.addActionListener(f -> { Connection c; if ((c = (Connection) StopsLinesComboBox.getSelectedItem()) != null) { @@ -316,35 +317,28 @@ public class View extends JFrame { } }); - ButtonLocation.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { + ButtonLocation.addActionListener(e -> { + String cur = TextLocation.getText(); + if (!cur.isEmpty()) { CardPanel.removeAll(); - String cur = TextLocation.getText(); LoadStringStops(cur); LoadSearchResultItinerary(searchResPath, modelItinerary); - System.out.println("search location clicked with text " + cur); CardPanel.add(ItineraryPanel); - - CardPanel.repaint(); - CardPanel.revalidate(); } + CardPanel.repaint(); + CardPanel.revalidate(); }); - ButtonCoord.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { + ButtonCoord.addActionListener(e -> { + String cur = TextCoord.getText(); + if (!cur.isEmpty()) { CardPanel.removeAll(); - String cur = TextCoord.getText(); - System.out.println(cur); LoadStringCoords(cur); LoadSearchResultItinerary(searchResPath, modelItinerary); - System.out.println("search coord clicked with text " + cur); CardPanel.add(ItineraryPanel); - - CardPanel.repaint(); - CardPanel.revalidate(); } + CardPanel.repaint(); + CardPanel.revalidate(); }); tableStops.addMouseListener(new MouseAdapter() { @@ -422,16 +416,13 @@ public class View extends JFrame { } public void LoadStringCoords(String stops){ - System.out.println(stops); stops = stops.replaceAll("[()]", "").replaceAll(";", ","); String[] stops_array = stops.split(","); double[] coords = new double[4]; - System.out.println(Arrays.toString(stops_array)); for (int i = 0; i < 4; i++){ coords[i] = Double.parseDouble(stops_array[i]); } searchResPath = (ArrayList) finder.findPath(coords[0], coords[1], coords[2], coords[3], LocalDateTime.now().toLocalTime().toSecondOfDay()); - } public void LoadStringStops(String stops){ @@ -443,7 +434,7 @@ public class View extends JFrame { for (int i = 0; i < 2;i++){ coords[j] = cur[i]; ++j; - } + } } searchResPath = (ArrayList) finder.findPath(coords[0], coords[1], coords[2], coords[3], LocalDateTime.now().toLocalTime().toSecondOfDay()); } @@ -460,21 +451,10 @@ public class View extends JFrame { count = 0; for (Stop stop : stops) { // Add a row to the table with Stop's line in the first column and Stop's name in the second column - model.addRow(new Object[]{String.join(",", stop.getLines()), stop.getName()}); ++count; } - System.out.println(stops.toString()); - for (int i = 0; i < model.getRowCount(); i++) { - for (int j = 0; j < model.getColumnCount(); j++) { - System.out.print("valeur at coord " + i +";" + j +": " + model.getValueAt(i, j) + "\t"); - } - System.out.println(); - } - - System.out.println(count); - tableStops.revalidate(); tableStops.repaint(); paneStops.setViewportView(tableStops); @@ -490,7 +470,6 @@ public class View extends JFrame { model.setRowCount(0); model.setColumnCount(cols); - // Add new rows based on the search results count = 0; Path last = null; @@ -501,24 +480,14 @@ public class View extends JFrame { int hours = (int) (time / 3600); int minutes = (int) ((time % 3600) / 60); - - model.addRow(new Object[]{path.getLine(), path.getCurrentStop(), String.format("%02d:%02d", hours, minutes)}); ++count; last = path; } } - if (last != null) model.addRow(new Object[]{last.getLine(), last.getNextStop()}); - - System.out.println(paths); - for (int i = 0; i < model.getRowCount(); i++) { - for (int j = 0; j < model.getColumnCount(); j++) { - System.out.print("valeur at coord " + i +";" + j +": " + model.getValueAt(i, j) + "\t"); - } - System.out.println(); - } - System.out.println(count); + if (last != null) + model.addRow(new Object[]{last.getLine(), last.getNextStop()}); tableItinerary.revalidate(); tableItinerary.repaint(); @@ -527,17 +496,6 @@ public class View extends JFrame { paneItinerary.repaint(); ItineraryPanel.revalidate(); ItineraryPanel.repaint(); - this.displayTableValues(model); - } - - public void displayTableValues(TableModel mod) { - for (int row = 0; row < mod.getRowCount(); row++) { - for (int column = 0; column < mod.getColumnCount(); column++) { - if (mod.getValueAt(row, column) != null) System.out.print(mod.getValueAt(row, column).toString() + " "); - } - System.out.print(";"); - } - System.out.println(); } private void openWebpage(URI uri) { @@ -558,13 +516,4 @@ public class View extends JFrame { LOGGER.severe("Default desktop browser not set"); } } - - /* - public static void main(String[] args) { - ArrayList s = new ArrayList<>(); - s.add(new Stop("M8", "Balard", 1.0315897, 3.0265513)); - s.add(new Stop("M14", "Gare de Lyon", 2.4658452681, 3.0265513)); - SwingUtilities.invokeLater(() -> new View(graph, finder, s)); - } - */ }