Merge branch 'dev' into 'gui-displayres-javadoc'
# Conflicts: # src/main/java/fr/u_paris/gla/project/gui/View.java
This commit is contained in:
commit
7e6c9d8ec7
16 changed files with 90 additions and 127 deletions
6
.gitignore
vendored
6
.gitignore
vendored
|
@ -1,8 +1,10 @@
|
|||
# Maven
|
||||
target/
|
||||
|
||||
# Files
|
||||
.csv
|
||||
# Generated files
|
||||
hours.csv
|
||||
images.csv
|
||||
trace.csv
|
||||
|
||||
# IDEs
|
||||
# Eclipse
|
||||
|
|
21
README.md
21
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.
|
||||
|
|
|
@ -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<Path> 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();
|
||||
|
|
|
@ -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) {
|
||||
CardPanel.removeAll();
|
||||
ButtonLocation.addActionListener(e -> {
|
||||
String cur = TextLocation.getText();
|
||||
if (!cur.isEmpty()) {
|
||||
CardPanel.removeAll();
|
||||
LoadStringStops(cur);
|
||||
LoadSearchResultItinerary(searchResPath, modelItinerary);
|
||||
System.out.println("search location clicked with text " + cur);
|
||||
CardPanel.add(ItineraryPanel);
|
||||
|
||||
}
|
||||
CardPanel.repaint();
|
||||
CardPanel.revalidate();
|
||||
}
|
||||
});
|
||||
|
||||
ButtonCoord.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
CardPanel.removeAll();
|
||||
ButtonCoord.addActionListener(e -> {
|
||||
String cur = TextCoord.getText();
|
||||
System.out.println(cur);
|
||||
if (!cur.isEmpty()) {
|
||||
CardPanel.removeAll();
|
||||
LoadStringCoords(cur);
|
||||
LoadSearchResultItinerary(searchResPath, modelItinerary);
|
||||
System.out.println("search coord clicked with text " + cur);
|
||||
CardPanel.add(ItineraryPanel);
|
||||
|
||||
}
|
||||
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<Path>) finder.findPath(coords[0], coords[1], coords[2], coords[3], LocalDateTime.now().toLocalTime().toSecondOfDay());
|
||||
|
||||
}
|
||||
|
||||
/** Load all stops related to locations
|
||||
|
@ -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<Stop> 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));
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
|
|
@ -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<ImagePair> 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));
|
||||
});
|
||||
}
|
||||
|
|
|
@ -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()) {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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){
|
||||
|
|
|
@ -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.
|
||||
*/
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -27,7 +27,12 @@ public class Finder {
|
|||
graph.addNode(fromNode);
|
||||
graph.addNode(toNode);
|
||||
|
||||
return findPath(fromNode, toNode, startTime);
|
||||
List<Path> result = findPath(fromNode, toNode, startTime);
|
||||
|
||||
graph.removeNode(fromNode);
|
||||
graph.removeNode(toNode);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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<Connection> 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);
|
||||
}
|
||||
|
|
|
@ -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<Stop> getNeighbors() {
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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<String[][]> 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));
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
}
|
||||
|
|
|
@ -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.");
|
||||
|
|
Reference in a new issue