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 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/gui/View.java b/src/main/java/fr/u_paris/gla/project/gui/View.java index d3cb19e..db68df7 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() { @@ -433,16 +427,13 @@ public class View extends JFrame { * @param stops a String in format (x1,y1);(x2,y2) */ 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()); - } /** Load all stops related to locations @@ -457,7 +448,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()); } @@ -477,21 +468,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); @@ -512,7 +492,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; @@ -523,24 +502,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(); @@ -549,7 +518,6 @@ public class View extends JFrame { paneItinerary.repaint(); ItineraryPanel.revalidate(); ItineraryPanel.repaint(); - this.displayTableValues(model); } /** Takes a table's data as argument and displays it @@ -589,13 +557,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)); - } - */ } 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 fe8133f..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() { @@ -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/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/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() { 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)); - // } - // } - // } - } 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.");