[format] use google codestyle

This commit is contained in:
Mylloon 2024-04-28 15:58:22 +02:00
parent db471f41d1
commit 27a34f390e
Signed by: Anri
GPG key ID: A82D63DFF8D1317F
40 changed files with 3037 additions and 2846 deletions

View file

@ -1,28 +1,37 @@
# Comment contribuer à ce projet
2 cas sont possibles pour contribuer à ce projet:
- Vous ête un étudiant et l'utilisez pour créer votre projet, dans ce cas reportez vous à [la section étudiant](#etudiant)
- Vous êtes un enseignant améliorant ce modèle, dans ce cas reportez vous à [la section enseignant](#enseignant)
- Vous ête un étudiant et l'utilisez pour créer votre projet, dans ce cas reportez vous
à [la section étudiant](#etudiant)
- Vous êtes un enseignant améliorant ce modèle, dans ce cas reportez vous
à [la section enseignant](#enseignant)
## Etudiant
Vous ne devez pas contribuer directement à ce projet mais devez en effectuer un fork. Une fois cela effectué vous devez:
- [X] Ajouter votre identifiant de groupe au champs `groupId` du fichier [pom.xml](pom.xml) sous la forme de `fr.u-paris.gla.votreequipe`
Vous ne devez pas contribuer directement à ce projet mais devez en effectuer un fork. Une fois cela
effectué vous devez:
- [x] Ajouter votre identifiant de groupe au champs `groupId` du fichier [pom.xml](pom.xml) sous la
forme de `fr.u-paris.gla.votreequipe`
- [ ] Modifier le package principal afin de refleter le nouveau nom de groupe.
- [ ] Adapter le fichier [README](README.md) au contenu de votre projet specifique
- [ ] Adapter ce fichier (CONTRIBUTING.md) à vos propres instructions de contribution, notamment:
- [ ] Convention de style de codage
- [ ] Convention d'utilisation de git
- [ ] Lien avec d'autres projets et d'autres dépôts.
- [X] Modifier le fichier `application.properties` au besoin.
- [x] Modifier le fichier `application.properties` au besoin.
## Enseignant
Ce dépôt suit la convention de gitflow. Les modifications doivent être effectuées dans des branches séparées,
Ce dépôt suit la convention de gitflow. Les modifications doivent être effectuées dans des branches
séparées,
intégrées dans la branche dev une fois terminée.
La branche main ne doit contenir que des versions stables de ce modèle.
Le code est écrit en Java, manipulé par l'outils de construction maven et doit suivre les conventions usuelles du langage et de l'outils.
Le code est écrit en Java, manipulé par l'outils de construction maven et doit suivre les
conventions usuelles du langage et de l'outils.
Le package principal du code Java est `fr.u_paris.gla.project`
Le fichier de properties `application.properties` permet d'accéder depuis le code Java aux diverses informations inscrite dans maven.
Le fichier de properties `application.properties` permet d'accéder depuis le code Java aux diverses
informations inscrite dans maven.

View file

@ -6,7 +6,8 @@ Version 2024
Ceci est l'archétype de projet de Génie Logiciel Avancé (GLA).
Il s'agit d'un projet Java. Ce dépôt définit un système de build et une application simple. Il est nécessaire de consulter le fichier [CONTRIBUTING.md](CONTRIBUTING.md) pour utiliser ce dépôt.
Il s'agit d'un projet Java. Ce dépôt définit un système de build et une application simple. Il est
nécessaire de consulter le fichier [CONTRIBUTING.md](CONTRIBUTING.md) pour utiliser ce dépôt.
## Lancement du programme
@ -27,9 +28,11 @@ 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.
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:
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
@ -37,7 +40,8 @@ java -jar target/project-2024.1.0.0-SNAPSHOT.jar --info
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.
L'option de lancement `--gui` causera l'ouverture d'une fenêtre affichant le logo de l'Université de
Paris.
## Tests JaCoCo

View file

@ -8,34 +8,44 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.PrintStream;
import java.util.Properties;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.WindowConstants;
/** Simple application model.
/**
* Simple application model.
*
* @author Emmanuel Bigeon */
* @author Emmanuel Bigeon
*/
public class App {
/**
*
*/
private static final String UNSPECIFIED = "Unspecified"; //$NON-NLS-1$
/** The logo image name. */
/**
* The logo image name.
*/
private static final String LOGO_NAME = "uparis_logo_rvb.png"; //$NON-NLS-1$
/** Image height. */
/**
* Image height.
*/
private static final int HEIGHT = 256;
/** Image width. */
/**
* Image width.
*/
private static final int WIDTH = HEIGHT;
/** Resizes an image.
/**
* Resizes an image.
*
* @param src source image
* @param w width
* @param h height
* @return the resized image */
* @return the resized image
*/
private static Image getScaledImage(Image src, int w, int h) {
BufferedImage resizedImg = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
Graphics2D g2d = resizedImg.createGraphics();
@ -46,11 +56,12 @@ public class App {
return resizedImg;
}
/** Application entry point.
/**
* Application entry point.
*
* @param args launching arguments */
* @param args launching arguments
*/
public static void main(String[] args) {
if (args.length > 0) {
for (String string : args) {
if ("--info".equals(string)) { //$NON-NLS-1$
printAppInfos(System.out);
@ -61,14 +72,17 @@ public class App {
}
}
}
}
/** @param out the output stream */
/**
* @param out the output stream
*/
public static void printAppInfos(PrintStream out) {
Properties props = readApplicationProperties();
out.println("Application: " + props.getProperty("app.name", UNSPECIFIED)); //$NON-NLS-1$ //$NON-NLS-2$
out.println("Version: " + props.getProperty("app.version", UNSPECIFIED)); //$NON-NLS-1$ //$NON-NLS-2$
out.println(
"Application: " + props.getProperty("app.name", UNSPECIFIED)); //$NON-NLS-1$ //$NON-NLS-2$
out.println(
"Version: " + props.getProperty("app.version", UNSPECIFIED)); //$NON-NLS-1$ //$NON-NLS-2$
out.println("By: " + props.getProperty("app.team", UNSPECIFIED)); //$NON-NLS-1$ //$NON-NLS-2$
}
@ -82,7 +96,9 @@ public class App {
return props;
}
/** Shows the logo in an image. */
/**
* Shows the logo in an image.
*/
public static void showLogo() {
Properties props = readApplicationProperties();

View file

@ -1,51 +1,61 @@
package fr.u_paris.gla.project.gui;
import fr.u_paris.gla.project.itinerary.Stop;
import javax.swing.*;
import java.awt.CardLayout;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.HeadlessException;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableModel;
import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
public class View extends JFrame {
private JPanel CardPanel;
private JMenuItem Home;
private JMenuItem Network;
private final JPanel CardPanel;
private final JMenuItem Home;
private final JMenuItem Network;
private final JPanel NetworkPanel;
private final JTextField TextLocation;
private final JButton ButtonLocation;
private final JPanel HomePanel;
private final JPanel MainPanel;
private final DefaultTableModel modelStops;
private final JTable tableStops;
private final JTable tableItinerary;
private final DefaultTableModel modelItinerary;
private final JScrollPane paneStops;
private final JScrollPane paneItinerary;
private final JPanel ItineraryPanel;
private final JMenuItem Itinerary;
private final JPanel stationsPanel;
private final JLabel departText;
private final JLabel arrText;
private final JTextField TextCoord;
private final JButton ButtonCoord;
private final JPanel SearchCoordPanel;
private final JPanel SearchLocationPanel;
private final JLabel NetworkLabel;
private final JMenuBar ButtonBar;
private final ArrayList<Stop> StopList;
private JMenuItem Favorites;
private JPanel NetworkPanel;
private JTextField TextLocation;
private JButton ButtonLocation;
private JPanel HomePanel;
private JPanel MainPanel;
private DefaultTableModel modelStops;
private JTable tableStops;
private JTable tableItinerary;
private DefaultTableModel modelItinerary;
private JScrollPane paneStops;
private JScrollPane paneItinerary;
private JPanel ItineraryPanel;
private JMenuItem Itinerary;
private JPanel stationsPanel;
private JLabel departText;
private JLabel arrText;
private JTextField TextCoord;
private JButton ButtonCoord;
private JPanel SearchCoordPanel;
private JPanel SearchLocationPanel;
private JLabel NetworkLabel;
private JLabel FavLabel;
private JMenuBar ButtonBar;
private ArrayList<Stop> StopList;
private String departureCur;
private String arrivalCur;
@ -106,8 +116,6 @@ public class View extends JFrame {
paneStops.add(tableStops);
NetworkPanel.add(paneStops);
ItineraryPanel = new JPanel();
CardPanel.add(ItineraryPanel);
GridLayout ItineraryLayout = new GridLayout(2, 1);
@ -117,7 +125,6 @@ public class View extends JFrame {
paneItinerary.add(tableItinerary);
ItineraryPanel.add(paneItinerary);
ButtonBar = new JMenuBar();
GridLayout ButtonLayout = new GridLayout(3, 1);
ButtonBar.setLayout(ButtonLayout);
@ -133,7 +140,6 @@ public class View extends JFrame {
MainPanel.add(ButtonBar);
MainPanel.add(CardPanel);
modelStops = (DefaultTableModel) tableStops.getModel();
modelStops.setColumnCount(2);
modelStops.setColumnIdentifiers(new Object[]{"Line", "Stop"});
@ -143,13 +149,11 @@ public class View extends JFrame {
modelItinerary.setColumnIdentifiers(new Object[]{"Line", "Stop", "Time"});
this.StopList = s;
setContentPane(MainPanel);
setTitle("app");
setExtendedState(JFrame.MAXIMIZED_BOTH);
//setUndecorated(true);
setVisible(true);
;
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Home.addActionListener(new ActionListener() {
@ -186,9 +190,6 @@ public class View extends JFrame {
}
});
TextLocation.addKeyListener(new KeyAdapter() {
@Override
public void keyReleased(KeyEvent e) {
@ -244,8 +245,6 @@ public class View extends JFrame {
}
});
paneStops.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
@ -254,6 +253,15 @@ public class View extends JFrame {
});
}
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));
View v = new View(s);
}
private void showOptionsDialog(JTable table, int x, int y) {
int selectedRow = table.rowAtPoint(new Point(x, y));
if (selectedRow != -1) { // If a row is selected
@ -262,8 +270,10 @@ public class View extends JFrame {
// Options to set Departure, Arrival, or Cancel
Object[] options = {"Departure", "Arrival", "Cancel"};
int choice = JOptionPane.showOptionDialog(null, "What action would you like to perform for " + stationSel + "?", "Action Selection",
JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE, null, options, options[2]);
int choice = JOptionPane.showOptionDialog(null,
"What action would you like to perform for " + stationSel + "?", "Action Selection",
JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE, null, options,
options[2]);
// Handling the choice
if (choice == 0) {
@ -279,27 +289,12 @@ public class View extends JFrame {
}
}
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));
View v = new View(s);
}
public void LoadSearchResult(ArrayList<Stop> stops, DefaultTableModel model) {
// Clear existing rows from the table
int cols = model.getColumnCount();
model.setRowCount(0);
model.setColumnCount(cols);
// Add new rows based on the search results
count = 0;
for (Stop stop : stops) {
@ -309,10 +304,10 @@ public class View extends JFrame {
++count;
}
System.out.println(stops.toString());
System.out.println(stops);
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.print("valeur at coord " + i + ";" + j + ": " + model.getValueAt(i, j) + "\t");
}
System.out.println();
}
@ -329,19 +324,16 @@ public class View extends JFrame {
paneStops.revalidate();
paneStops.repaint();
paneItinerary.setViewportView(tableItinerary);
paneItinerary.revalidate();
paneItinerary.repaint();
NetworkPanel.revalidate();
NetworkPanel.repaint();
ItineraryPanel.revalidate();
ItineraryPanel.repaint();
this.displayTableValues(model);
}
@ -351,7 +343,9 @@ public class View extends JFrame {
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() + " ");
if (mod.getValueAt(row, column) != null) {
System.out.print(mod.getValueAt(row, column).toString() + " ");
}
}
System.out.print(";");

View file

@ -1,17 +1,17 @@
package fr.u_paris.gla.project.idfm;
/**
* A representation of a stop with the bifurcation that is needed. All stops
* have a list of bifstop called connected. BifStop is just composed of a
* connected stop and the bifurcation used to go from the first stop to the
* connected one.
* A representation of a stop with the bifurcation that is needed. All stops have a list of bifstop
* called connected. BifStop is just composed of a connected stop and the bifurcation used to go
* from the first stop to the connected one.
*/
public class BifStop {
// The bifurcation
public int bifurc;
public Stop stop;
public BifStop(int bif, Stop stop){
public BifStop(int bif, Stop stop) {
bifurc = bif;
this.stop = stop;
}

View file

@ -3,26 +3,17 @@
*/
package fr.u_paris.gla.project.idfm;
import fr.u_paris.gla.project.io.ScheduleFormat;
import java.text.MessageFormat;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import fr.u_paris.gla.project.io.ImageFormat;
import fr.u_paris.gla.project.utils.GPS;
import java.text.NumberFormat;
import java.util.Arrays;
import java.util.Iterator;
import java.util.Locale;
public final class CSVImageProvider {
private static final NumberFormat MINUTES_SECOND_FORMATTER = NumberFormat
.getInstance(Locale.ENGLISH);
static {
MINUTES_SECOND_FORMATTER.setMinimumIntegerDigits(2);
}
@ -30,17 +21,23 @@ public final class CSVImageProvider {
private final String[] line = new String[ImageFormat.NUMBER_COLUMNS];
private final Iterator<Transport> current;
/** Create the stream provider */
/**
* Create the stream provider
*/
public CSVImageProvider(Iterator<Transport> traces) {
this.current = traces;
}
/** Check if next exists */
/**
* Check if next exists
*/
public boolean hasNext() {
return this.current.hasNext();
}
/** Get Next element */
/**
* Get Next element
*/
public String[] next() {
if (!this.hasNext()) {
return null;

View file

@ -1,32 +1,32 @@
package fr.u_paris.gla.project.idfm;
import fr.u_paris.gla.project.io.ScheduleFormat;
import java.text.NumberFormat;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.time.Duration;
import java.time.LocalDateTime;
// import java.time.format.ResolverStyle;
import java.text.NumberFormat;
import java.util.*;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Locale;
import java.util.Random;
public class CSVSchedulesProvider {
private static final DateTimeFormatter HOUR_MINUTE_FORMATTER = ScheduleFormat.getTimeFormatter();
private static final HashMap<String, int[]> timings = new HashMap<String, int[]>(){{
private static final HashMap<String, int[]> timings = new HashMap<String, int[]>() {{
put("Bus", new int[]{11, 8, 7});
put("Funicular", new int[]{15, 25, 20});
put("Tram", new int[]{6, 7, 8, 9});
put("Rail", new int[]{10, 11,15,12,20});
put("Subway", new int[]{4, 2, 6,3,3,4});
put("Rail", new int[]{10, 11, 15, 12, 20});
put("Subway", new int[]{4, 2, 6, 3, 3, 4});
}};
// Time between 2 passages for the transports with a new type we don't know yet
private static int DEFAULT_TIMING = 6;
private static final NumberFormat MINUTES_SECOND_FORMATTER = NumberFormat
.getInstance(Locale.ENGLISH);
// Time between 2 passages for the transports with a new type we don't know yet
private static final int DEFAULT_TIMING = 6;
static {
MINUTES_SECOND_FORMATTER.setMinimumIntegerDigits(2);
@ -41,8 +41,6 @@ public class CSVSchedulesProvider {
private LocalDateTime lastHour = null;
/**
* Create the stream provider
*/
@ -50,21 +48,46 @@ public class CSVSchedulesProvider {
this.currentTransport = transports;
}
/**
* @param transportType the type of a transport
* @return a random minute depending on the type of the transport
*/
public static int pickMinute(String transportType) {
if (!timings.containsKey(transportType)) {
return DEFAULT_TIMING;
}
int[] temps = timings.get(transportType);
Random random = new Random();
int indexAleatoire = random.nextInt(temps.length);
return temps[indexAleatoire];
}
/**
* @param hourMinute hour and minute representation. Ex: "14:03"
* @return a datetime of today but using hourMinute
*/
public static LocalDateTime convertIntoLocalDateTime(String hourMinute) {
LocalDateTime aujourdHui = LocalDateTime.now();
LocalTime time = LocalTime.parse(hourMinute, HOUR_MINUTE_FORMATTER);
return aujourdHui.withHour(time.getHour()).withMinute(time.getMinute()).withSecond(0)
.withNano(0);
}
public boolean hasNext() {
return currentTransport.hasNext() || currentDescription.hasNext();
}
private void skipToNext() {
if(currentHour == null || lastHour == null){
if (currentHour == null || lastHour == null) {
skipToNextTransport();
}else if(currentHour.compareTo(lastHour) < 0){
} else if (currentHour.isBefore(lastHour)) {
// System.out.println("**Skip: Le current hour est plus petit "+currentHour+"|||"+lastHour);
addRandomMinutes();
}else if (currentHour.compareTo(lastHour) >= 0) {
} else if (!currentHour.isBefore(lastHour)) {
// System.out.println("**Skip: Le current hour est plus grand "+currentHour+"|||"+lastHour);
skipToNextDescription();
}
else if (!this.currentDescription.hasNext()) {
} else if (!this.currentDescription.hasNext()) {
skipToNextTransport();
}
@ -80,19 +103,18 @@ public class CSVSchedulesProvider {
currentHour = convertIntoLocalDateTime(description.first);
lastHour = convertIntoLocalDateTime(description.last);
if(lastHour.compareTo(currentHour) <= 0){
if (!lastHour.isAfter(currentHour)) {
lastHour = lastHour.plusDays(1);
}
this.line[ScheduleFormat.TERMINUS_INDEX] = description.from;
this.line[ScheduleFormat.TRIP_SEQUENCE_INDEX] = description.bifurcation.toString();
this.line[ScheduleFormat.TIME_INDEX] = currentHour.format(HOUR_MINUTE_FORMATTER);
}else{
} else {
skipToNextTransport();
}
}
/**
* Move to the next Transport line
*/
@ -119,8 +141,8 @@ public class CSVSchedulesProvider {
}
/**
* Add random minutes for the next passage of a transport.
* The random minutes depends on the type of the transport
* Add random minutes for the next passage of a transport. The random minutes depends on the type
* of the transport
*/
private void addRandomMinutes() {
// System.out.println("** addM: AVANT: "+currentHour);
@ -130,31 +152,4 @@ public class CSVSchedulesProvider {
// debut ++;
// if(debut == 7) throw new IllegalArgumentException();
}
/**
*
* @param transportType the type of a transport
* @return a random minute depending on the type of the transport
*/
public static int pickMinute(String transportType) {
if (!timings.containsKey(transportType)) {
return DEFAULT_TIMING;
}
int[] temps = timings.get(transportType);
Random random = new Random();
int indexAleatoire = random.nextInt(temps.length);
return temps[indexAleatoire];
}
/**
*
* @param hourMinute hour and minute representation. Ex: "14:03"
* @return a datetime of today but using hourMinute
*/
public static LocalDateTime convertIntoLocalDateTime(String hourMinute) {
LocalDateTime aujourdHui = LocalDateTime.now();
LocalTime time = LocalTime.parse(hourMinute, HOUR_MINUTE_FORMATTER);
return aujourdHui.withHour(time.getHour()).withMinute(time.getMinute()).withSecond(0).withNano(0);
}
}

View file

@ -3,6 +3,8 @@
*/
package fr.u_paris.gla.project.idfm;
import fr.u_paris.gla.project.io.NetworkFormat;
import fr.u_paris.gla.project.utils.GPS;
import java.text.MessageFormat;
import java.text.NumberFormat;
import java.util.ArrayList;
@ -16,15 +18,12 @@ import java.util.Locale;
import java.util.Map;
import java.util.Set;
import fr.u_paris.gla.project.io.NetworkFormat;
import fr.u_paris.gla.project.utils.GPS;
/**
* CSV Stream Provider class
*/
public final class CSVStreamProvider {
private static final HashMap<String, Double> two_acceleration_distance_by_type = new HashMap<String, Double>(){{
private static final HashMap<String, Double> two_acceleration_distance_by_type = new HashMap<String, Double>() {{
put("Bus", 0.1);
put("Funicular", 0.1);
put("Tram", 0.1);
@ -32,7 +31,7 @@ public final class CSVStreamProvider {
put("Subway", 0.1);
}};
private static final HashMap<String, Double> max_speed_by_type = new HashMap<String, Double>(){{
private static final HashMap<String, Double> max_speed_by_type = new HashMap<String, Double>() {{
put("Bus", 10.0);
put("Funicular", 5.0);
put("Tram", 20.0);
@ -50,21 +49,28 @@ public final class CSVStreamProvider {
*/
private static final NumberFormat MINUTES_SECOND_FORMATTER = NumberFormat
.getInstance(Locale.ENGLISH);
static {
MINUTES_SECOND_FORMATTER.setMinimumIntegerDigits(2);
}
/** Number of seconds in a minute. */
/**
* Number of seconds in a minute.
*/
private static final int SECONDS_IN_MINUTES = 60;
/**
* Number of seconds in an hour
*/
private static final long SECONDS_IN_HOURS = 3_600;
// Magically chosen values
/** Maximal speed in km/h */
/**
* Maximal speed in km/h
*/
private static final double MAX_SPEED = 5;
/** Distance to reach maximal speed in km */
// Magically chosen values
/**
* Distance to reach maximal speed in km
*/
private static final double TWO_ACCELERATION_DISTANCE = 0.2;
static {
MINUTES_SECOND_FORMATTER.setMinimumIntegerDigits(2);
}
/**
* Current CSV Line
*/
@ -74,6 +80,13 @@ public final class CSVStreamProvider {
* Current CSV transport line iterator
*/
private final Iterator<TraceEntry> currentTrace;
// The transport id with its value
private final Map<String, Transport> transports;
/**
* HashMap of the current line's segments
*/
Map<StopEntry, Set<StopEntry>> lineSegments = new HashMap<>();
List<TraceDescription> descriptions = new ArrayList<>();
/**
* Current Stop path iterator
*/
@ -86,15 +99,6 @@ public final class CSVStreamProvider {
* current iterator for the end of the line
*/
private Iterator<StopEntry> currentSegmentEnd = Collections.emptyIterator();
/**
* HashMap of the current line's segments
*/
Map<StopEntry, Set<StopEntry>> lineSegments = new HashMap<>();
// The transport id with its value
private final Map<String, Transport> transports;
List <TraceDescription> descriptions = new ArrayList<>();
/**
* current begin of line
*/
@ -117,15 +121,63 @@ public final class CSVStreamProvider {
private String traceType = "";
private String url_image = "";
/** Create the stream provider
/**
* Create the stream provider
*
* @param traces an iterator of the possible traces
* @param t map of transports */
* @param t map of transports
*/
public CSVStreamProvider(Iterator<TraceEntry> traces, Map<String, Transport> t) {
this.currentTrace = traces;
transports = t;
}
/** Method that tells if we have segments or paths to go through
/**
* creates adds a station into the next line String
*
* @param stop the stop
* @param nextLine the next line
* @param index the stop index in the next line
*/
private static void fillStation(StopEntry stop, String[] nextLine, int index) {
nextLine[index] = stop.lname;
nextLine[index + 1] = MessageFormat.format("{0}, {1}", //$NON-NLS-1$
GPS_FORMATTER.format(stop.latitude),
GPS_FORMATTER.format(stop.longitude));
}
/**
* turns a number into a formatted time string
*
* @param time the time value
* @return the time as a String
*/
private static String formatTime(long time) {
return MessageFormat.format("{0}:{1}", //$NON-NLS-1$
MINUTES_SECOND_FORMATTER.format(time / SECONDS_IN_MINUTES),
MINUTES_SECOND_FORMATTER.format(time % SECONDS_IN_MINUTES));
}
/**
* A tool method to give a delay to go through a certain distance.
* <p>
* This is a model with an linear acceleration and deceleration periods and a constant speed in
* between.
*
* @param distance the distance (in km)
* @return the duration of the trip (in hours)
*/
private static double distanceToTime(double distance, String type) {
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);
}
/**
* Method that tells if we have segments or paths to go through
*
* @return if there are next elements or not
*/
public boolean hasNext() {
@ -170,8 +222,9 @@ public final class CSVStreamProvider {
}
}
/** Move the reading head of path to the next one that has at least two
* elements */
/**
* Move the reading head of path to the next one that has at least two elements
*/
private void skipToNextCandidatePath() {
currentSegmentStart = null;
do {
@ -202,7 +255,21 @@ public final class CSVStreamProvider {
} while (currentSegmentStart == null);
}
/** Store current trace' data as a String array
// /** A tool method to give a delay to go through a certain distance.
// * <p>
// * This is a model with an linear acceleration and deceleration periods and a
// * constant speed in between.
// *
// * @param distance the distance (in km)
// * @return the duration of the trip (in hours) */
// private static double distanceToTime(double distance) {
// return Math.max(0, distance - TWO_ACCELERATION_DISTANCE) / MAX_SPEED
// + Math.pow(Math.min(distance, TWO_ACCELERATION_DISTANCE) / MAX_SPEED, 2);
// }
/**
* Store current trace' data as a String array
*
* @return The newly generated line of text
*/
public String[] next() {
@ -218,7 +285,7 @@ public final class CSVStreamProvider {
this.line[NetworkFormat.DISTANCE_INDEX] = NumberFormat.getInstance(Locale.ENGLISH)
.format(distance);
this.line[NetworkFormat.DURATION_INDEX] = formatTime(
(long) Math.ceil(distanceToTime(distance,this.traceType) * SECONDS_IN_HOURS));
(long) Math.ceil(distanceToTime(distance, this.traceType) * SECONDS_IN_HOURS));
int bifurcation = this.lineSegments.get(this.start).size() - 1;
this.line[NetworkFormat.VARIANT_INDEX] = Integer
.toString(bifurcation);
@ -228,68 +295,22 @@ public final class CSVStreamProvider {
}
/** creates adds a station into the next line String
* @param stop the stop
* @param nextLine the next line
* @param index the stop index in the next line */
private static void fillStation(StopEntry stop, String[] nextLine, int index) {
nextLine[index] = stop.lname;
nextLine[index + 1] = MessageFormat.format("{0}, {1}", //$NON-NLS-1$
GPS_FORMATTER.format(stop.latitude),
GPS_FORMATTER.format(stop.longitude));
}
/** turns a number into a formatted time string
* @param time the time value
* @return the time as a String */
private static String formatTime(long time) {
return MessageFormat.format("{0}:{1}", //$NON-NLS-1$
MINUTES_SECOND_FORMATTER.format(time / SECONDS_IN_MINUTES), MINUTES_SECOND_FORMATTER.format(time % SECONDS_IN_MINUTES));
}
// /** A tool method to give a delay to go through a certain distance.
// * <p>
// * This is a model with an linear acceleration and deceleration periods and a
// * constant speed in between.
// *
// * @param distance the distance (in km)
// * @return the duration of the trip (in hours) */
// private static double distanceToTime(double distance) {
// return Math.max(0, distance - TWO_ACCELERATION_DISTANCE) / MAX_SPEED
// + Math.pow(Math.min(distance, TWO_ACCELERATION_DISTANCE) / MAX_SPEED, 2);
// }
/** A tool method to give a delay to go through a certain distance.
* <p>
* This is a model with an linear acceleration and deceleration periods and a
* constant speed in between.
*
* @param distance the distance (in km)
* @return the duration of the trip (in hours) */
private static double distanceToTime(double distance, String type) {
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);
}
private void fillTransports(int bif) {
if(transports != null){
if (transports != null) {
String nameTransport = this.line[NetworkFormat.LINE_INDEX];
String start_p = this.line[NetworkFormat.START_INDEX];
String end_p = this.line[NetworkFormat.STOP_INDEX];
// String bifurcation = this.line[NetworkFormat.VARIANT_INDEX];
Transport transp = null;
if(!transports.containsKey(traceId)){
transp = new Transport(nameTransport,traceType, url_image);
if (!transports.containsKey(traceId)) {
transp = new Transport(nameTransport, traceType, url_image);
transports.put(traceId, transp);
}else{
} else {
transp = transports.get(traceId);
}
transp.addStop(start_p, end_p, bif);
if(transp.descriptions.isEmpty()){
if (transp.descriptions.isEmpty()) {
transp.addDescriptions(descriptions);
}
}

View file

@ -5,18 +5,22 @@ package fr.u_paris.gla.project.idfm;
import fr.u_paris.gla.project.utils.CSVTools;
import fr.u_paris.gla.project.utils.GPS;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.IOException;
import java.io.File;
import java.io.IOException;
import java.text.MessageFormat;
import java.util.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.stream.Stream;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
/**
* Code of an extractor for the data from IDF mobilite.
@ -101,7 +105,7 @@ public class IDFMNetworkExtractor {
public static boolean checkFileExistence(String filePath) {
File file = new File(filePath);
if (file.exists()) {
LOGGER.severe(filePath+ " already exists.");
LOGGER.severe(filePath + " already exists.");
return true;
} else {
LOGGER.severe(filePath + " does not exist.");
@ -111,7 +115,7 @@ public class IDFMNetworkExtractor {
public static void buildFiles() {
if (checkFileExistence("./"+HOURS_FILE_NAME) && checkFileExistence("./"+TRACE_FILE_NAME)) {
if (checkFileExistence("./" + HOURS_FILE_NAME) && checkFileExistence("./" + TRACE_FILE_NAME)) {
LOGGER.severe("Files already exists.");
return;
}
@ -160,11 +164,14 @@ public class IDFMNetworkExtractor {
long seconds = (tempsPasse / 1000) % 60;
long milliseconds = tempsPasse % 1000;
System.out.println("Temps écoulé : " + minutes + " minutess, " + seconds + " secndes et " + milliseconds + " millis");
System.out.println(
"Temps écoulé : " + minutes + " minutess, " + seconds + " secndes et " + milliseconds
+ " millis");
System.out.println("******************Fin Building bifurcations ************************");
CSVSchedulesProvider providerschedules = new CSVSchedulesProvider(transports.values().iterator());
CSVSchedulesProvider providerschedules = new CSVSchedulesProvider(
transports.values().iterator());
try {
CSVTools.writeCSVToFile(HOURS_FILE_NAME, Stream.iterate(providerschedules.next(),
t -> providerschedules.hasNext(), t -> providerschedules.next()));
@ -184,7 +191,9 @@ public class IDFMNetworkExtractor {
}
/** Clean the traces/remove the unresolved lines
/**
* Clean the traces/remove the unresolved lines
*
* @param traces the traces to clean
*/
private static void cleanTraces(Map<String, TraceEntry> traces) {
@ -202,9 +211,12 @@ public class IDFMNetworkExtractor {
}
}
/** Tells if the current trasport line has all its stops entries resolved
/**
* Tells if the current trasport line has all its stops entries resolved
*
* @param stops the stops list
* @return if the line is "clean"*/
* @return if the line is "clean"
*/
private static boolean cleanLine(List<List<StopEntry>> stops) {
for (List<StopEntry> path : stops) {
for (int i = 0; i < path.size(); i++) {
@ -222,7 +234,9 @@ public class IDFMNetworkExtractor {
return true;
}
/** adds a stop to all related variables
/**
* adds a stop to all related variables
*
* @param line the transport line involved with the new stop
* @param traces the traces related to it
* @param stops the general stops list
@ -243,10 +257,10 @@ public class IDFMNetworkExtractor {
}
}
// Add terminus to the traces
if (traces.containsKey(rid)) {
extractTerminus(line[IDFM_STOPS_SCHEDULES_INDEX]).forEach(t -> traces.get(rid).addTerminus(t));
extractTerminus(line[IDFM_STOPS_SCHEDULES_INDEX]).forEach(
t -> traces.get(rid).addTerminus(t));
}
traces.computeIfPresent(rid,
@ -254,12 +268,15 @@ public class IDFMNetworkExtractor {
stops.add(entry);
}
/** add a line to the related list of traces
/**
* add a line to the related list of traces
*
* @param line the line as a string
* @param traces the traces
*/
private static void addLine(String[] line, Map<String, TraceEntry> traces) {
TraceEntry entry = new TraceEntry(line[IDFM_TRACE_SNAME_INDEX], line[IDFM_TRACE_ID_INDEX],line[IDFM_TRACE_TYPE_INDEX], line[IDFM_URL_INDEX]);
TraceEntry entry = new TraceEntry(line[IDFM_TRACE_SNAME_INDEX], line[IDFM_TRACE_ID_INDEX],
line[IDFM_TRACE_TYPE_INDEX], line[IDFM_URL_INDEX]);
List<List<StopEntry>> buildPaths = buildPaths(line[IDFM_TRACE_SHAPE_INDEX]);
entry.getPaths().addAll(buildPaths);
if (buildPaths.isEmpty()) {
@ -270,7 +287,9 @@ public class IDFMNetworkExtractor {
}
}
/** add a new entry as a candidate to a trace
/**
* add a new entry as a candidate to a trace
*
* @param trace the trace
* @param entry the entry
* @return the trace in question
@ -289,7 +308,9 @@ public class IDFMNetworkExtractor {
return trace;
}
/** turn a JSON list of stops into a list of paths
/**
* turn a JSON list of stops into a list of paths
*
* @param pathsJSON the JSON String of all paths
* @return the paths as a List of StopEntries
*/
@ -320,7 +341,9 @@ public class IDFMNetworkExtractor {
return all;
}
/** extract the terminus out of a JSON file
/**
* extract the terminus out of a JSON file
*
* @param JSON the JSON
* @return a list of strings related to the terminus
*/

View file

@ -1,25 +1,24 @@
package fr.u_paris.gla.project.idfm;
import java.util.List;
import java.util.Map;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
/**
* A representation of a stop with its connected stop and which bifurcation
* is needed to go to each connected stop
* A representation of a stop with its connected stop and which bifurcation is needed to go to each
* connected stop
*/
public class Stop {
Map<String, BifStop> connected = new HashMap<>();
public String name;
Map<String, BifStop> connected = new HashMap<>();
public Stop(String name){
public Stop(String name) {
this.name = name;
}
/**
* Checks is stopName is connected to this one
*
* @param stopName
* @return True if stopName is connected to the current stop
*/
@ -29,6 +28,7 @@ public class Stop {
/**
* Add Connected stop
*
* @param stop connected stop with the bifurcation needed
*/
public void addConnectedStop(BifStop stop) {
@ -37,6 +37,7 @@ public class Stop {
/**
* Return the connected stop with the name : stopName
*
* @param stopName
* @return the connected stop with the name : stopName
*/

View file

@ -10,6 +10,7 @@ import java.util.Objects;
*
* @author Emmanuel Bigeon */
public class StopEntry implements Comparable<StopEntry> {
public final String lname;
public final double longitude;
public final double latitude;
@ -56,12 +57,15 @@ public class StopEntry implements Comparable<StopEntry> {
@Override
public boolean equals(Object obj) {
if (this == obj)
if (this == obj) {
return true;
if (obj == null)
}
if (obj == null) {
return false;
if (getClass() != obj.getClass())
}
if (getClass() != obj.getClass()) {
return false;
}
StopEntry other = (StopEntry) obj;
return Double.doubleToLongBits(latitude) == Double
.doubleToLongBits(other.latitude) && Objects.equals(lname, other.lname)

View file

@ -1,21 +1,22 @@
package fr.u_paris.gla.project.idfm;
import java.util.List;
import java.util.ArrayList;
import java.util.List;
/**
* A representation of a transport description encompansing its first and last
* stop in all of its direction, the first and last schedule and all the
* bifurcation that direction takes. The description comes from the fourth column * of the stop csv file.
* A representation of a transport description encompansing its first and last stop in all of its
* direction, the first and last schedule and all the bifurcation that direction takes. The
* description comes from the fourth column * of the stop csv file.
*/
public class TraceDescription {
public String from;
public String to;
public String first;
public String last;
List<Integer> bifurcation = new ArrayList<>();
public TraceDescription(String from,String to, String first, String last){
public TraceDescription(String from, String to, String first, String last) {
this.from = from;
this.to = to;
this.first = first;
@ -24,6 +25,7 @@ public class TraceDescription {
@Override
public String toString() {
return "From: " + from + ", To: " + to + ", First: " + first + ", Last: " + last + ", Bifurcation: " + bifurcation;
return "From: " + from + ", To: " + to + ", First: " + first + ", Last: " + last
+ ", Bifurcation: " + bifurcation;
}
}

View file

@ -12,16 +12,14 @@ import java.util.List;
* @author Emmanuel Bigeon
*/
public final class TraceEntry {
public final String lname;
public final String id;
public final String type;
public final String url;
private List<String> terminus = new ArrayList<>();
private List<List<StopEntry>> paths = new ArrayList<>();
List <TraceDescription> descriptions = new ArrayList<>();
private final List<String> terminus = new ArrayList<>();
private final List<List<StopEntry>> paths = new ArrayList<>();
List<TraceDescription> descriptions = new ArrayList<>();
/**
@ -29,7 +27,7 @@ public final class TraceEntry {
*
* @param lname the name of the line
*/
public TraceEntry(String lname,String ident,String t_type, String img_url) {
public TraceEntry(String lname, String ident, String t_type, String img_url) {
super();
this.lname = lname;
this.id = ident;
@ -38,13 +36,18 @@ public final class TraceEntry {
}
// FIXME list of lists are bad practice in direct access...
/** @return the list of paths */
/**
* @return the list of paths
*/
public List<List<StopEntry>> getPaths() {
// TODO Ne pas retourner directement la liste
return paths;
}
/** @return the list of terminus */
/**
* @return the list of terminus
*/
public List<String> getTerminus() {
return terminus;
}
@ -57,15 +60,16 @@ public final class TraceEntry {
terminus.add(term);
}
public boolean isDescriptionEmpty(){
public boolean isDescriptionEmpty() {
return descriptions.isEmpty();
}
/**
* Add all the description to the current one
*
* @param desctipt
*/
public void addDescriptions(List<TraceDescription> desctipt){
public void addDescriptions(List<TraceDescription> desctipt) {
descriptions.addAll(desctipt);
}
}

View file

@ -1,29 +1,28 @@
package fr.u_paris.gla.project.idfm;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.AbstractMap.SimpleEntry;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.AbstractMap.SimpleEntry;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* Representation of a line with its description and stops
*/
public class Transport {
//All the stops of the line
Map<String, Stop> stopsMap = new HashMap<>();
public String name;
public String type;
public String image_url;
//All the stops of the line
Map<String, Stop> stopsMap = new HashMap<>();
//All the line descriptions (directions and schedules)
List <TraceDescription> descriptions = new ArrayList<>();
List<TraceDescription> descriptions = new ArrayList<>();
public Transport(String name,String type, String url){
public Transport(String name, String type, String url) {
this.name = name;
this.type = type;
this.image_url = url;
@ -33,15 +32,16 @@ public class Transport {
/**
* Build the bifurcation for all the descriptions
*/
public void buildBifurcation(){
public void buildBifurcation() {
// int found = 0;
for(TraceDescription d : descriptions){
for (TraceDescription d : descriptions) {
// System.out.println("Debut est "+d.first);
Stop debut = stopsMap.get(d.from);
Stop fin = stopsMap.get(d.to);
if (debut != null && fin != null) {
SimpleEntry<Boolean, List<Integer>> sol = roadToLast(debut.name, fin.name, new ArrayList<String>(), new ArrayList<Integer>());
SimpleEntry<Boolean, List<Integer>> sol = roadToLast(debut.name, fin.name,
new ArrayList<String>(), new ArrayList<Integer>());
if (sol.getKey()) {
// found++;
d.bifurcation = sol.getValue();
@ -62,7 +62,8 @@ public class Transport {
Stop fin = stopsMap.get(d.to);
if (debut != null && fin != null) {
Set<String> alreadyVisited = new HashSet<>();
SimpleEntry<Boolean, List<Integer>> sol = roadToLastOptimized(debut.name, fin.name, alreadyVisited, new ArrayList<Integer>());
SimpleEntry<Boolean, List<Integer>> sol = roadToLastOptimized(debut.name, fin.name,
alreadyVisited, new ArrayList<Integer>());
if (sol.getKey()) {
// found++;
d.bifurcation = sol.getValue();
@ -75,75 +76,78 @@ public class Transport {
/**
* Check if the stop is a terminus
*
* @param stop the name of a Stop
* @return True if the stop is a terminus
*/
public boolean isTerminus(String stop){
for(TraceDescription t: descriptions){
if(stop.equals(t.first) || stop.equals(t.last))
public boolean isTerminus(String stop) {
for (TraceDescription t : descriptions) {
if (stop.equals(t.first) || stop.equals(t.last)) {
return true;
}
}
return false;
}
/**
* Find the road from the currentStop to the last stop
*
* @param currentStop the current stop we are visiting
* @param last The last stop we are trying to go to
* @param alreadyVisited All the stop we already have visisted
* @param bif All the bifurcation encountered from the first stop to the current
* one
* @return True and the bifurcation if we found our road to the last stop and
* false if we didn't
* @param bif All the bifurcation encountered from the first stop to the current one
* @return True and the bifurcation if we found our road to the last stop and false if we didn't
*/
public SimpleEntry<Boolean,List<Integer> > roadToLast(String currentStop, String last, List<String> alreadyVisited, List<Integer> bifurcation){
public SimpleEntry<Boolean, List<Integer>> roadToLast(String currentStop, String last,
List<String> alreadyVisited, List<Integer> bifurcation) {
if(currentStop.equals(last)){
return new SimpleEntry<>(true,bifurcation);
if (currentStop.equals(last)) {
return new SimpleEntry<>(true, bifurcation);
}
//Checker if the current stop is the bad terminus
if(isTerminus(currentStop)){
return new SimpleEntry<>(false,null);
if (isTerminus(currentStop)) {
return new SimpleEntry<>(false, null);
}
List<String> visitedCopy = new ArrayList<>(alreadyVisited);
visitedCopy.add(currentStop);
Stop current = stopsMap.get(currentStop);
List <SimpleEntry<Boolean,List<Integer>> > solutions = new ArrayList<>();
for(BifStop b: current.connected.values()){
if(!visitedCopy.contains(b.stop.name)){
List<SimpleEntry<Boolean, List<Integer>>> solutions = new ArrayList<>();
for (BifStop b : current.connected.values()) {
if (!visitedCopy.contains(b.stop.name)) {
List<Integer> bifCopy = new ArrayList<>(bifurcation);
if(b.bifurc!= 0)
if (b.bifurc != 0) {
bifCopy.add(b.bifurc);
}
solutions.add(roadToLast(b.stop.name, last, visitedCopy, bifCopy));
}
}
//TODo: Send a list on list of integer in case there is a lot of path for the same direction
List<Integer> bifSol = new ArrayList<>();
boolean trouve = false;
for(SimpleEntry<Boolean,List<Integer>> se: solutions){
if(se.getKey()){
for (SimpleEntry<Boolean, List<Integer>> se : solutions) {
if (se.getKey()) {
trouve = true;
bifSol = se.getValue();
}
}
return new SimpleEntry<>(trouve,bifSol) ;
return new SimpleEntry<>(trouve, bifSol);
}
/**
* Find the road from the currentStop to the last stop
*
* @param currentStop the current stop we are visiting
* @param last The last stop we are trying to go to
* @param alreadyVisited All the stop we already have visisted
* @param bif All the bifurcation encountered from the first stop to the current
* one
* @return True and the bifurcation if we found our road to the last stop and
* false if we didn't
* @param bif All the bifurcation encountered from the first stop to the current one
* @return True and the bifurcation if we found our road to the last stop and false if we didn't
*/
public SimpleEntry<Boolean, List<Integer>> roadToLastOptimized(String currentStop, String last, Set<String> alreadyVisited, List<Integer> bifurcation) {
public SimpleEntry<Boolean, List<Integer>> roadToLastOptimized(String currentStop, String last,
Set<String> alreadyVisited, List<Integer> bifurcation) {
if (currentStop.equals(last)) {
return new SimpleEntry<>(true, bifurcation);
}
@ -186,11 +190,12 @@ public class Transport {
/**
* Connect 2 stops (start, end) and add them in stopMap if they are not already in
*
* @param start The name of a stop
* @param end The name of the stop connected to the start
* @param bifurcation The bifurcation taken to go from start stop to end stop
*/
public void addStop(String start, String end, int bifurcation){
public void addStop(String start, String end, int bifurcation) {
Stop startStop = stopsMap.computeIfAbsent(start, Stop::new);
Stop endStop = stopsMap.computeIfAbsent(end, Stop::new);
@ -216,9 +221,10 @@ public class Transport {
/**
* Add all the description to the current one
*
* @param desctipt
*/
public void addDescriptions(List<TraceDescription> desctipt){
public void addDescriptions(List<TraceDescription> desctipt) {
descriptions.addAll(desctipt);
}

View file

@ -3,6 +3,7 @@
*/
package fr.u_paris.gla.project.idfm;
import fr.u_paris.gla.project.utils.GPS;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Collections;
@ -10,19 +11,21 @@ import java.util.Comparator;
import java.util.List;
import java.util.Objects;
import fr.u_paris.gla.project.utils.GPS;
/** A transport stop with unidentified name and potential candidates as to their
* real value.
/**
* A transport stop with unidentified name and potential candidates as to their real value.
*
* @author Emmanuel Bigeon */
* @author Emmanuel Bigeon
*/
public final class UnidentifiedStopEntry extends StopEntry {
private List<StopEntry> candidates = new ArrayList<>();
/** Create the stop
private final List<StopEntry> candidates = new ArrayList<>();
/**
* Create the stop
*
* @param longitude
* @param latitude */
* @param latitude
*/
public UnidentifiedStopEntry(double longitude, double latitude) {
super("Unidentified", longitude, latitude); //$NON-NLS-1$
}
@ -32,9 +35,11 @@ public final class UnidentifiedStopEntry extends StopEntry {
return MessageFormat.format("UnidentifiedStop [candidates={0}]", this.candidates); //$NON-NLS-1$
}
/** Get the most likely choice for the stop
/**
* Get the most likely choice for the stop
*
* @return the most likely candidate */
* @return the most likely candidate
*/
public StopEntry resolve() {
if (candidates.isEmpty()) {
return null;
@ -50,21 +55,26 @@ public final class UnidentifiedStopEntry extends StopEntry {
return candidates.get(0);
}
/** Add a candidate.
/**
* Add a candidate.
*
* @param entry the candidate */
* @param entry the candidate
*/
public void addCandidate(StopEntry entry) {
candidates.add(entry);
}
@Override
public boolean equals(Object obj) {
if (this == obj)
if (this == obj) {
return true;
if (!super.equals(obj))
}
if (!super.equals(obj)) {
return false;
if (getClass() != obj.getClass())
}
if (getClass() != obj.getClass()) {
return false;
}
UnidentifiedStopEntry other = (UnidentifiedStopEntry) obj;
return Objects.equals(candidates, other.candidates);
}

View file

@ -3,21 +3,19 @@
*/
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.
*/
public final class ImageFormat {
public static final int NUMBER_COLUMNS = 2;
public static final int LINE_INDEX = 0;
public static final int IMAGE_URL_INDEX = 1;
/** Hidden constructor for tool class */
/**
* Hidden constructor for tool class
*/
private ImageFormat() {
// Tool class
}

View file

@ -14,6 +14,7 @@ import java.util.Locale;
*
* @author Emmanuel Bigeon */
public final class NetworkFormat {
/** The amount of columns in the CSV file */
public static final int NUMBER_COLUMNS = 8;
@ -37,10 +38,11 @@ public final class NetworkFormat {
.ofPattern("HH:mm:ss");
private static final NumberFormat DURATION_INDIVIDUAL_FORMATTER = NumberFormat
.getIntegerInstance(Locale.ENGLISH);
private static final Temporal ZERO = LocalTime.parse("00:00:00");
static {
DURATION_INDIVIDUAL_FORMATTER.setMinimumIntegerDigits(2);
}
private static final Temporal ZERO = LocalTime.parse("00:00:00");
/** Hidden constructor for utility class */
private NetworkFormat() {

View file

@ -14,19 +14,32 @@ import java.util.List;
* @author Emmanuel Bigeon
*/
public final class ScheduleFormat {
/** The amount of columns in the CSV file */
/**
* The amount of columns in the CSV file
*/
public static final int NUMBER_COLUMNS = 4;
/** The index of the line name in the schedule format */
/**
* The index of the line name in the schedule format
*/
public static final int LINE_INDEX = 0;
/** The index of the trip sequence in the schedule format */
/**
* The index of the trip sequence in the schedule format
*/
public static final int TRIP_SEQUENCE_INDEX = 1;
/** The index of the terminus name in the schedule format */
/**
* The index of the terminus name in the schedule format
*/
public static final int TERMINUS_INDEX = 2;
/** The index of the time in the schedule format */
/**
* The index of the time in the schedule format
*/
public static final int TIME_INDEX = 3;
/** Hidden constructor for tool class */
/**
* Hidden constructor for tool class
*/
private ScheduleFormat() {
// Tool class
}
@ -40,13 +53,16 @@ public final class ScheduleFormat {
public static List<Integer> getTripSequence(String representation) {
List<Integer> l = new ArrayList<>();
for(String s : representation.split(","))
for (String s : representation.split(",")) {
l.add(Integer.parseInt(s));
}
return l;
}
/** Create a {@link java.time.format.DateTimeFormatter} object used to format Dates
/**
* Create a {@link java.time.format.DateTimeFormatter} object used to format Dates
*
* @return the formatter
*/
public static DateTimeFormatter getTimeFormatter() {

View file

@ -3,7 +3,8 @@ package fr.u_paris.gla.project.itinerary;
import java.util.ArrayList;
import java.util.Collections;
public class Connection{
public class Connection {
// Destination of the connection between the two stops
private final Stop stop;
@ -20,16 +21,16 @@ public class Connection{
private final int bifurcation;
public Connection(Stop stop, String lineName, double distance, int time, int bifurcation){
public Connection(Stop stop, String lineName, double distance, int time, int bifurcation) {
this.stop = stop;
this.lineName=lineName;
this.lineName = lineName;
this.distance = distance;
this.time = time;
this.schedules = new ArrayList<>();
this.bifurcation = bifurcation;
}
public Connection(Stop stop, String lineName, double distance, int time){
public Connection(Stop stop, String lineName, double distance, int time) {
this(stop, lineName, distance, time, 0);
}
@ -71,29 +72,31 @@ public class Connection{
}
public double getNextTime(double currentTime) {
if(this.schedules.size() == 0) {
if (this.schedules.size() == 0) {
return currentTime;
}
int i = 0;
while(i < this.schedules.size() && this.schedules.get(i) < currentTime) {
while (i < this.schedules.size() && this.schedules.get(i) < currentTime) {
i++;
}
if(i < this.schedules.size()) {
if (i < this.schedules.size()) {
return this.schedules.get(i);
}
return this.schedules.get(0);
}
public double getCost(double currentTime) {
if(this.schedules.size() == 0) {
if(this.lineName.equals("WALK")) {
if (this.schedules.size() == 0) {
if (this.lineName.equals("WALK")) {
return this.time;
}
return this.time + 900;
}
double nextTime = this.getNextTime(currentTime);
if(nextTime < currentTime) { nextTime += 86400;}
if (nextTime < currentTime) {
nextTime += 86400;
}
return nextTime - currentTime + this.time;
}
}

View file

@ -1,17 +1,24 @@
package fr.u_paris.gla.project.itinerary;
import java.util.*;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.PriorityQueue;
public class Finder {
private Graph graph;
private final Graph graph;
public Finder(Graph graph) {
this.graph = graph;
}
/**
* return a path from startNode to goalNode using A* algorithm
*
* @param startNode
* @param goalNode
*/
@ -45,7 +52,7 @@ public class Finder {
closedSet.add(current);
if(graph.getConnections(current) == null) {
if (graph.getConnections(current) == null) {
continue;
}
@ -69,8 +76,7 @@ public class Finder {
if (!openSet.contains(neighbor)) {
neighbor.setF(fScore.get(neighbor));
openSet.add(neighbor);
}
else {
} else {
updatePriority(openSet, neighbor, fScore.get(neighbor));
}
}
@ -82,6 +88,7 @@ public class Finder {
/**
* Once we found the destination we reconstruct the path
*
* @param cameFrom
* @param current
* @return path
@ -92,8 +99,9 @@ public class Finder {
while (cameFrom.containsKey(current)) {
current = cameFrom.get(current).getCurrentStop();
if(cameFrom.get(current) != null) {
totalPath.add(0, cameFrom.get(current)); // Add to the beginning of the list to maintain order
if (cameFrom.get(current) != null) {
totalPath.add(0,
cameFrom.get(current)); // Add to the beginning of the list to maintain order
}
}
@ -102,6 +110,7 @@ public class Finder {
/**
* Update the priority queue
*
* @param openSet
* @param node
* @param newF

View file

@ -1,10 +1,10 @@
package fr.u_paris.gla.project.itinerary;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class Graph{
public class Graph {
private final Set<Stop> nodes;
private final Map<Stop, Set<Connection>> connections;

View file

@ -1,14 +1,18 @@
package fr.u_paris.gla.project.itinerary;
import java.util.List;
import java.util.Set;
public interface GraphNode {
int getId();
double getHeuristicCost(Stop goalNode);
Set<Stop> getNeighbors();
double getCost(Stop neighbor);
double getF();
void setF(double value);
}

View file

@ -1,15 +1,19 @@
package fr.u_paris.gla.project.itinerary;
import fr.u_paris.gla.project.idfm.*;
import fr.u_paris.gla.project.idfm.IDFMNetworkExtractor;
import fr.u_paris.gla.project.utils.CSVTools;
import fr.u_paris.gla.project.utils.GPS;
import java.io.IOException;
import java.util.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
public class Parse {
private static final Logger LOGGER = Logger
.getLogger(IDFMNetworkExtractor.class.getName());
@ -28,7 +32,7 @@ public class Parse {
private static final int IDFM_TRACE_FROM_GPS_INDEX = 3;
private static final int IDFM_TRACE_TO_INDEX= 4;
private static final int IDFM_TRACE_TO_INDEX = 4;
private static final int IDFM_TRACE_TO_GPS_INDEX = 5;
@ -44,23 +48,25 @@ public class Parse {
//Walking speed in m/s
private static final double WALK_SPEED = 1.;
private HashSet<Stop> nodes = new HashSet<>();
private HashMap<Stop, Set<Connection>> connections = new HashMap<>();
private HashMap<String, ArrayList<Stop>> tmp = new HashMap<>();
private final HashSet<Stop> nodes = new HashSet<>();
private final HashMap<Stop, Set<Connection>> connections = new HashMap<>();
private final HashMap<String, ArrayList<Stop>> tmp = new HashMap<>();
/**
* Returns the coordinates from a String to a double array:
* "49.08, 3.07" -> {49.08, 3.07}
* Returns the coordinates from a String to a double array: "49.08, 3.07" -> {49.08, 3.07}
*
* @param gps the string representation
* @return the double array
*/
private static double[] getCoords(String gps) {
String []stringCoords = gps.split(", ");
return new double[] {Double.parseDouble(stringCoords[0]), Double.parseDouble(stringCoords[1])};
String[] stringCoords = gps.split(", ");
return new double[]{Double.parseDouble(stringCoords[0]), Double.parseDouble(stringCoords[1])};
}
/**
* Searchs for a stop with the same name and GPS coordinates in the graph, and creates it if non existant
* Searchs for a stop with the same name and GPS coordinates in the graph, and creates it if non
* existant
*
* @param nodes a graph of the stops
* @param tmp list of the created stops
* @param name the name of the stop
@ -68,21 +74,22 @@ public class Parse {
* @param lineId the line the stop is on
* @return the Stop object
*/
private static Stop getOrCreateStop(HashSet<Stop> nodes, HashMap<String, ArrayList<Stop>> tmp, String name, String gps, String lineId, HashMap<Stop, Set<Connection>> connections) {
private static Stop getOrCreateStop(HashSet<Stop> nodes, HashMap<String, ArrayList<Stop>> tmp,
String name, String gps, String lineId, HashMap<Stop, Set<Connection>> connections) {
ArrayList<Stop> stopList = tmp.get(name);
double[] coords = getCoords(gps);
// First we search by name, and then compare the coordinates since multiple stations can have the same name. A margin of error is necessary since stops can have multiple GPS coordinates
ArrayList<Stop> lineChanges = new ArrayList<>();
if (stopList != null) {
for(Stop stop : stopList) {
for (Stop stop : stopList) {
double dist = GPS.distance(coords[0], coords[1], stop.getLatitude(), stop.getLongitude());
if(dist == 0) {
if (dist == 0) {
stop.addLine(lineId);
return stop;
}
if(dist < ERROR_MARGIN) {
if (dist < ERROR_MARGIN) {
lineChanges.add(stop);
}
}
@ -93,9 +100,9 @@ public class Parse {
stopList = stopList == null ? new ArrayList<>() : stopList;
stopList.add(newStop);
tmp.put(name, stopList);
for(Stop s : lineChanges) {
for (Stop s : lineChanges) {
double dist = GPS.distance(coords[0], coords[1], s.getLatitude(), s.getLongitude());
int time = (int) (dist*1000/WALK_SPEED);
int time = (int) (dist * 1000 / WALK_SPEED);
Connection c1 = new Connection(s, "WALK", dist, time);
connections.computeIfAbsent(newStop, k -> new HashSet<>()).add(c1);
@ -107,87 +114,103 @@ public class Parse {
/**
* Adds into the graph the connection between two stops, parsed from a CSV line
*
* @param line the current line we want to parse
* @param nodes the graph of stops
* @param tmp list of the created stops
* @param connections
*/
private static void addLine(String[] line, HashSet<Stop> nodes, HashMap<String, ArrayList<Stop>> tmp, HashMap<Stop, Set<Connection>> connections) {
Stop fromStop = getOrCreateStop(nodes, tmp, line[IDFM_TRACE_FROM_INDEX], line[IDFM_TRACE_FROM_GPS_INDEX], line[IDFM_TRACE_ID_INDEX], connections);
Stop toStop = getOrCreateStop(nodes, tmp, line[IDFM_TRACE_TO_INDEX], line[IDFM_TRACE_TO_GPS_INDEX], line[IDFM_TRACE_ID_INDEX], connections);
private static void addLine(String[] line, HashSet<Stop> nodes,
HashMap<String, ArrayList<Stop>> tmp, HashMap<Stop, Set<Connection>> connections) {
Stop fromStop = getOrCreateStop(nodes, tmp, line[IDFM_TRACE_FROM_INDEX],
line[IDFM_TRACE_FROM_GPS_INDEX], line[IDFM_TRACE_ID_INDEX], connections);
Stop toStop = getOrCreateStop(nodes, tmp, line[IDFM_TRACE_TO_INDEX],
line[IDFM_TRACE_TO_GPS_INDEX], line[IDFM_TRACE_ID_INDEX], connections);
String[] timeString = line[IDFM_TRACE_TIME_INDEX].split(":");
String time0WithoutComma = timeString[0].replace(",", "");
int time = Integer.parseInt(time0WithoutComma) * 60 + Integer.parseInt(timeString[1]);
Connection connection = new Connection(toStop, line[IDFM_TRACE_ID_INDEX], Double.parseDouble(line[IDFM_TRACE_DISTANCE_INDEX]), time, Integer.parseInt(line[IDFM_TRACE_DERIV_INDEX]));
Connection connection = new Connection(toStop, line[IDFM_TRACE_ID_INDEX],
Double.parseDouble(line[IDFM_TRACE_DISTANCE_INDEX]), time,
Integer.parseInt(line[IDFM_TRACE_DERIV_INDEX]));
connections.computeIfAbsent(fromStop, k -> new HashSet<>()).add(connection);
}
private static void addScheduleRec(Stop current, Stop previous, String line, ArrayList<Integer> bifurcations, int time, HashMap<String, ArrayList<Stop>> stopsHashSet, HashMap<Stop, Set<Connection>> connections, HashSet<Stop> processed){
time = time%86400;
private static void addScheduleRec(Stop current, Stop previous, String line,
ArrayList<Integer> bifurcations, int time, HashMap<String, ArrayList<Stop>> stopsHashSet,
HashMap<Stop, Set<Connection>> connections, HashSet<Stop> processed) {
time = time % 86400;
//If the stop has already been processed, it is not reprocessed.
if(processed.contains(current)) {return;}
if (processed.contains(current)) {
return;
}
processed.add(current);
Set<Connection> neighborhood = connections.get(current);
if(neighborhood == null) {return;}
if (neighborhood == null) {
return;
}
ArrayList<Connection> directions = new ArrayList<>();
for(Connection n : neighborhood) {
if(n.getLineName().equals(line)
for (Connection n : neighborhood) {
if (n.getLineName().equals(line)
&& (previous == null || !n.getStop().getName().equals(previous.getName()))
) {
directions.add(n);
}
}
if(directions.size() == 0) {return;}
if (directions.size() == 0) {
return;
}
Stop next_stop = null;
if(directions.size() > 1) {
if (directions.size() > 1) {
int bifurcation = bifurcations.size() == 0 ? 0 : bifurcations.get(0);
if(bifurcations.size() > 0) {bifurcations.remove(0);}
for(Connection d : directions) {
if(d.getBifurcation() == bifurcation) {
if (bifurcations.size() > 0) {
bifurcations.remove(0);
}
for (Connection d : directions) {
if (d.getBifurcation() == bifurcation) {
next_stop = d.getStop();
break;
}
}
if(next_stop == null) {
if (next_stop == null) {
return;
}
}
else {
} else {
next_stop = directions.get(0).getStop();
if(directions.get(0).getBifurcation() != 0) {
if(bifurcations.size() > 0 && directions.get(0).getBifurcation() == bifurcations.get(0)){
if (directions.get(0).getBifurcation() != 0) {
if (bifurcations.size() > 0 && directions.get(0).getBifurcation() == bifurcations.get(0)) {
bifurcations.remove(0);
}
}
}
for(Connection n : directions) {
if(n.getStop() == next_stop) {
for (Connection n : directions) {
if (n.getStop() == next_stop) {
n.addSchedule(time);
time += n.getTime() + STOP_TIME;
addScheduleRec(next_stop, current, line, bifurcations, time, stopsHashSet, connections, processed);
addScheduleRec(next_stop, current, line, bifurcations, time, stopsHashSet, connections,
processed);
return;
}
}
}
private static void addSchedule(String[] input, HashMap<String, ArrayList<Stop>> stopsHashSet, HashMap<Stop, Set<Connection>> connections) {
private static void addSchedule(String[] input, HashMap<String, ArrayList<Stop>> stopsHashSet,
HashMap<Stop, Set<Connection>> connections) {
String line = input[0];
ArrayList<Integer> bifurcations = new ArrayList<>();
if(!input[1].equals("[]")) {
String[] b = input[1].substring(1, input[1].length()-1).split(",");
if (!input[1].equals("[]")) {
String[] b = input[1].substring(1, input[1].length() - 1).split(",");
bifurcations = new ArrayList<>();
for(String n : b){
for (String n : b) {
bifurcations.add(Integer.parseInt(n.trim()));
}
}
@ -195,20 +218,22 @@ public class Parse {
String name = input[2];
String[] timeString = input[3].split(":");
int time = Integer.parseInt(timeString[0]) * 3600 + Integer.parseInt(timeString[1])*60;
int time = Integer.parseInt(timeString[0]) * 3600 + Integer.parseInt(timeString[1]) * 60;
ArrayList<Stop> stops = stopsHashSet.get(name);
if(stops == null) {return;}
if (stops == null) {
return;
}
for(Stop stop : stops) {
if(stop.getLines().contains(line)) {
addScheduleRec(stop, null, line, bifurcations, time, stopsHashSet, connections, new HashSet<>());
for (Stop stop : stops) {
if (stop.getLines().contains(line)) {
addScheduleRec(stop, null, line, bifurcations, time, stopsHashSet, connections,
new HashSet<>());
}
}
}
public void parseFiles(){
public void parseFiles() {
IDFMNetworkExtractor.buildFiles();
@ -220,8 +245,8 @@ public class Parse {
CSVTools.readCSVFromFile(HOURS_FILE_NAME,
(String[] line) -> addSchedule(line, tmp, connections));
for(Set<Connection> set : connections.values()) {
for(Connection c : set) {
for (Set<Connection> set : connections.values()) {
for (Connection c : set) {
c.sortSchedule();
}
}
@ -232,7 +257,7 @@ public class Parse {
}
public List<Path> getItinerary(Stop src, Stop dst, double startTime ){
public List<Path> getItinerary(Stop src, Stop dst, double startTime) {
Graph graph = new Graph(nodes, connections);
Finder finder = new Finder(graph);
return finder.findPath(src, dst, startTime);

View file

@ -1,20 +1,18 @@
package fr.u_paris.gla.project.itinerary;
public class Path {
private Stop current;
private Stop next;
private final Stop current;
private double startTime;
private final Stop next;
private double travelTime;
private final double startTime;
private final double travelTime;
private final String line;
private final Connection connection;
private double distance;
private String line;
private Connection connection;
public Path(Stop current, Connection connection, double startTime) {
this.current = current;
this.connection = connection;
@ -24,7 +22,7 @@ public class Path {
this.line = connection.getLineName();
}
public Connection getConnection(){
public Connection getConnection() {
return this.connection;
}

View file

@ -4,6 +4,7 @@ import java.util.HashSet;
import java.util.Set;
public class Stop implements GraphNode {
// The total number of stops
private static int counter = 0;
@ -42,7 +43,7 @@ public class Stop implements GraphNode {
}
@Override
public int getId(){
public int getId() {
return id;
}
@ -70,21 +71,23 @@ public class Stop implements GraphNode {
this.f = value;
}
public String getName(){
public String getName() {
return name;
}
public double getLatitude(){
public double getLatitude() {
return latitude;
}
public double getLongitude(){
public double getLongitude() {
return longitude;
}
public void addLine(String s){
public void addLine(String s) {
lines.add(s);
}
public Set<String> getLines() { return this.lines; }
public Set<String> getLines() {
return this.lines;
}
}

View file

@ -1,19 +1,23 @@
package fr.u_paris.gla.project.utils;
import fr.u_paris.gla.project.idfm.IDFMNetworkExtractor;
import org.json.JSONArray;
import org.json.JSONObject;
import java.io.*;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.json.JSONArray;
import org.json.JSONObject;
public class ApiUtils {
/** The logger for information on the process */
/**
* The logger for information on the process
*/
private static final Logger LOGGER = Logger
.getLogger(IDFMNetworkExtractor.class.getName());
@ -22,7 +26,8 @@ public class ApiUtils {
public static double[] getGPSLocation(String term) {
try {
String urlString = String.format("%s?q=%s&format=json", OSM_URL, URLEncoder.encode(term, StandardCharsets.UTF_8));
String urlString = String.format("%s?q=%s&format=json", OSM_URL,
URLEncoder.encode(term, StandardCharsets.UTF_8));
HttpURLConnection connection = (HttpURLConnection) new URL(urlString).openConnection();
connection.setRequestMethod("GET");
@ -44,8 +49,7 @@ public class ApiUtils {
double lon = firstResult.getDouble("lon");
return new double[]{lat, lon};
}
}
catch (IOException e) {
} catch (IOException e) {
LOGGER.log(Level.SEVERE, e,
() -> "Error accessing the API");
}

View file

@ -3,13 +3,6 @@
*/
package fr.u_paris.gla.project.utils;
import java.io.*;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.function.Consumer;
import java.util.stream.Stream;
import com.opencsv.CSVParserBuilder;
import com.opencsv.CSVReader;
import com.opencsv.CSVReaderBuilder;
@ -17,18 +10,36 @@ import com.opencsv.CSVWriterBuilder;
import com.opencsv.ICSVParser;
import com.opencsv.ICSVWriter;
import com.opencsv.exceptions.CsvValidationException;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.function.Consumer;
import java.util.stream.Stream;
/** A CSV tool class.
/**
* A CSV tool class.
*
* @author Emmanuel Bigeon */
* @author Emmanuel Bigeon
*/
public final class CSVTools {
/** Hidden constructor of tool class */
/**
* Hidden constructor of tool class
*/
private CSVTools() {
// Tool class
}
/** get a CSV file from a URL, download and parse it, and keep values in memory
/**
* get a CSV file from a URL, download and parse it, and keep values in memory
*
* @param is the address of the CSV file
* @param contentLineConsumer the variable used to store the data
* @throws IOException if it's impossible to download the file
@ -53,7 +64,9 @@ public final class CSVTools {
}
/** get a CSV file from a file and parse it, keeping values in memory
/**
* get a CSV file from a file and parse it, keeping values in memory
*
* @param filename the saved file's name and path
* @param contentLineConsumer the variable used to store the data
* @throws IOException if it's impossible to read the file
@ -64,7 +77,9 @@ public final class CSVTools {
readCSVFromInputStream(new FileInputStream(file), contentLineConsumer);
}
/** get a CSV file from a URL, download and parse it, and keep values in memory
/**
* get a CSV file from a URL, download and parse it, and keep values in memory
*
* @param url the address of the CSV file
* @param contentLineConsumer the variable used to store the data
* @throws IOException if it's impossible to download the file
@ -74,7 +89,9 @@ public final class CSVTools {
readCSVFromInputStream(new URL(url).openStream(), contentLineConsumer);
}
/** Save our current CSV variable's data into an actual file
/**
* 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

View file

@ -4,9 +4,14 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
import org.junit.jupiter.api.Test;
/** Unit test for simple App. */
/**
* Unit test for simple App.
*/
class AppTest {
/** Rigorous Test :-) */
/**
* Rigorous Test :-)
*/
@Test
public void testPlaceholder() {
assertTrue(true, "It should be true that true is true...");

View file

@ -4,6 +4,9 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
import fr.u_paris.gla.project.io.NetworkFormat;
import fr.u_paris.gla.project.utils.GPS;
import java.lang.reflect.Method;
import java.text.MessageFormat;
import java.text.NumberFormat;
@ -12,8 +15,6 @@ import java.util.Collections;
import java.util.List;
import java.util.Locale;
import org.junit.jupiter.api.Test;
import fr.u_paris.gla.project.io.NetworkFormat;
import fr.u_paris.gla.project.utils.GPS;
public class CSVStreamProviderTest {
@ -21,23 +22,25 @@ public class CSVStreamProviderTest {
@Test
public void testHasNext() {
// Scénario sans Trace
CSVStreamProvider providerWithoutTrace = new CSVStreamProvider(Collections.emptyIterator(),null);
assertFalse(providerWithoutTrace.hasNext(), "hasNext should return false when no traces are provided");
CSVStreamProvider providerWithoutTrace = new CSVStreamProvider(Collections.emptyIterator(),
null);
assertFalse(providerWithoutTrace.hasNext(),
"hasNext should return false when no traces are provided");
// Scénario avec Trace
StopEntry stop1 = new StopEntry("Stop1", 2.3522, 48.8566);
StopEntry stop2 = new StopEntry("Stop2", 2.295, 48.8738);
List<StopEntry> path = Arrays.asList(stop1, stop2);
TraceEntry trace = new TraceEntry("Ligne1","IDFM:03434","Bus", "dummy_url");
TraceEntry trace = new TraceEntry("Ligne1", "IDFM:03434", "Bus", "dummy_url");
trace.addPath(path);
CSVStreamProvider providerWithTrace = new CSVStreamProvider(Arrays.asList(trace).iterator(),null);
CSVStreamProvider providerWithTrace = new CSVStreamProvider(List.of(trace).iterator(),
null);
assertTrue(providerWithTrace.hasNext(), "hasNext should return true when traces are provided");
}
//Test de la methode next()
@Test
public void testNext() {
@ -45,10 +48,11 @@ public class CSVStreamProviderTest {
StopEntry start = new StopEntry("Début", 2.3522, 48.8566); // Paris
StopEntry end = new StopEntry("Fin", 2.295, 48.8738); // Proche de Paris
TraceEntry traceEntry = new TraceEntry("Ligne1","IDFM:03434","Bus", "dummy_url");
TraceEntry traceEntry = new TraceEntry("Ligne1", "IDFM:03434", "Bus", "dummy_url");
traceEntry.addPath(Arrays.asList(start, end)); // Ajout d'un chemin à la trace
CSVStreamProvider provider = new CSVStreamProvider(Collections.singletonList(traceEntry).iterator(),null);
CSVStreamProvider provider = new CSVStreamProvider(
Collections.singletonList(traceEntry).iterator(), null);
assertTrue(provider.hasNext(), "Doit avoir un prochain élément");
@ -56,26 +60,32 @@ public class CSVStreamProviderTest {
assertNotNull(result, "Le résultat ne doit pas être null");
// Vérifications spécifiques sur le format des données de sortie
assertEquals(start.lname, result[NetworkFormat.START_INDEX], "Le nom de l'arrêt de départ doit correspondre");
assertEquals(end.lname, result[NetworkFormat.STOP_INDEX], "Le nom de l'arrêt d'arrivée doit correspondre");
assertEquals(start.lname, result[NetworkFormat.START_INDEX],
"Le nom de l'arrêt de départ doit correspondre");
assertEquals(end.lname, result[NetworkFormat.STOP_INDEX],
"Le nom de l'arrêt d'arrivée doit correspondre");
// Calcul et vérification de la distance attendue
double expectedDistance = GPS.distance(start.latitude, start.longitude, end.latitude, end.longitude);
String expectedDistanceFormatted = NumberFormat.getInstance(Locale.ENGLISH).format(expectedDistance);
assertEquals(expectedDistanceFormatted, result[NetworkFormat.DISTANCE_INDEX], "La distance doit correspondre");
double expectedDistance = GPS.distance(start.latitude, start.longitude, end.latitude,
end.longitude);
String expectedDistanceFormatted = NumberFormat.getInstance(Locale.ENGLISH)
.format(expectedDistance);
assertEquals(expectedDistanceFormatted, result[NetworkFormat.DISTANCE_INDEX],
"La distance doit correspondre");
}
//Test de la methode private fillStation avec la réflexion
@Test
public void testFillStation() throws Exception {
// Initialisation des données de test
StopEntry stop = new StopEntry("StopName", 2.3522, 48.8566); // Exemple de coordonnées pour Paris
StopEntry stop = new StopEntry("StopName", 2.3522,
48.8566); // Exemple de coordonnées pour Paris
String[] nextLine = new String[NetworkFormat.NUMBER_COLUMNS];
// Accès à la méthode fillStation via la réflexion
Method fillStationMethod = CSVStreamProvider.class.getDeclaredMethod("fillStation", StopEntry.class, String[].class, int.class);
Method fillStationMethod = CSVStreamProvider.class.getDeclaredMethod("fillStation",
StopEntry.class, String[].class, int.class);
fillStationMethod.setAccessible(true);
// Invocation de la méthode fillStation
@ -88,13 +98,13 @@ public class CSVStreamProviderTest {
gpsFormatter.format(stop.longitude));
// Vérifications
assertEquals(stop.lname, nextLine[NetworkFormat.START_INDEX], "Le nom de l'arrêt doit correspondre.");
assertEquals(expectedLatitudeLongitude, nextLine[NetworkFormat.START_INDEX + 1], "Les coordonnées GPS doivent correspondre.");
assertEquals(stop.lname, nextLine[NetworkFormat.START_INDEX],
"Le nom de l'arrêt doit correspondre.");
assertEquals(expectedLatitudeLongitude, nextLine[NetworkFormat.START_INDEX + 1],
"Les coordonnées GPS doivent correspondre.");
}
//Test de la méthode static private distanceToTime()
@Test
public void testDistanceToTime() throws Exception {
@ -117,6 +127,7 @@ public class CSVStreamProviderTest {
double result = (Double) method.invoke(null, distanceExample);
// 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.");
assertEquals(expected, result,
"Le calcul du temps à partir de la distance devrait être conforme à l'attendu.");
}
}

View file

@ -1,10 +1,13 @@
package fr.u_paris.gla.project.idfm;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.Test;
class IDFMNetworkExtractorTest {
@ -13,16 +16,18 @@ class IDFMNetworkExtractorTest {
@Test
public void testCleanLine() throws Exception {
// Création d'un arrêt non identifié avec des coordonnées spécifiques
UnidentifiedStopEntry unidentifiedStop = new UnidentifiedStopEntry(2.3522, 48.8566); // Coordonnées pour Paris
UnidentifiedStopEntry unidentifiedStop = new UnidentifiedStopEntry(2.3522,
48.8566); // Coordonnées pour Paris
// Création d'un arrêt candidat proche de l'arrêt non identifié
StopEntry closeCandidate = new StopEntry("Proche Candidat", 2.3523, 48.8567); // Coordonnées proches de Paris
StopEntry closeCandidate = new StopEntry("Proche Candidat", 2.3523,
48.8567); // Coordonnées proches de Paris
// Ajout du candidat à l'arrêt non identifié
unidentifiedStop.addCandidate(closeCandidate);
// Liste des chemins contenant l'arrêt non identifié
List<List<StopEntry>> paths = new ArrayList<>(Arrays.asList(Arrays.asList(unidentifiedStop)));
List<List<StopEntry>> paths = new ArrayList<>(List.of(List.of(unidentifiedStop)));
// Accès à la méthode cleanLine via la réflexion
Method cleanLineMethod = IDFMNetworkExtractor.class.getDeclaredMethod("cleanLine", List.class);
@ -33,22 +38,25 @@ class IDFMNetworkExtractorTest {
// Vérifications
assertTrue(result, "La méthode cleanLine devrait retourner true si le nettoyage a réussi.");
assertNotEquals("Unidentified", paths.get(0).get(0).lname, "L'arrêt non identifié devrait avoir été résolu.");
assertEquals(closeCandidate.lname, paths.get(0).get(0).lname, "L'arrêt devrait être résolu au candidat le plus proche.");
assertNotEquals("Unidentified", paths.get(0).get(0).lname,
"L'arrêt non identifié devrait avoir été résolu.");
assertEquals(closeCandidate.lname, paths.get(0).get(0).lname,
"L'arrêt devrait être résolu au candidat le plus proche.");
}
@Test
public void testAddCandidate() throws Exception {
UnidentifiedStopEntry unidentifiedStop = new UnidentifiedStopEntry(2.3522, 48.8566); // Coordonnées pour Paris
List<StopEntry> path = new ArrayList<>(Arrays.asList(unidentifiedStop));
TraceEntry trace = new TraceEntry("Ligne1","IDFM:03434","Bus", "dummy_url");
UnidentifiedStopEntry unidentifiedStop = new UnidentifiedStopEntry(2.3522,
48.8566); // Coordonnées pour Paris
List<StopEntry> path = new ArrayList<>(List.of(unidentifiedStop));
TraceEntry trace = new TraceEntry("Ligne1", "IDFM:03434", "Bus", "dummy_url");
trace.addPath(path);
StopEntry candidate = new StopEntry("Proche Candidat", 2.3523, 48.8567); // Coordonnées proches
Method method = IDFMNetworkExtractor.class.getDeclaredMethod("addCandidate", TraceEntry.class, StopEntry.class);
Method method = IDFMNetworkExtractor.class.getDeclaredMethod("addCandidate", TraceEntry.class,
StopEntry.class);
method.setAccessible(true);
method.invoke(null, trace, candidate);

View file

@ -1,6 +1,10 @@
package fr.u_paris.gla.project.idfm;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
public class StopEntryTest {
@ -15,7 +19,7 @@ public class StopEntryTest {
}
*/
//Si le le test testToString du haut ne marche pas essayer celui du bas
//Si le test testToString du haut ne marche pas essayer celui du bas
@Test
public void testToString() {
StopEntry stop = new StopEntry("Chatelet", 2.346, 48.853);
@ -33,11 +37,11 @@ public class StopEntryTest {
assertTrue(stop1.compareTo(stop2) < 0); //
assertTrue(stop2.compareTo(stop1) > 0); //
// Test avec la même latitude et longitude mais des noms différents
// Test avec la même latitude et longitude, mais des noms différents
StopEntry stop3 = new StopEntry("Chatelet", 2.3467, 48.8534);
assertEquals(0, stop1.compareTo(stop3));
// Test avec le même nom mais des emplacements différents
// Test avec le même nom, mais des emplacements différents
StopEntry stop4 = new StopEntry("Chatelet", 2.3500, 48.8500);
assertTrue(stop1.compareTo(stop4) > 0);
}

View file

@ -1,6 +1,10 @@
package fr.u_paris.gla.project.idfm;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
public class StopTest {
@ -55,7 +59,7 @@ public class StopTest {
@Test
public void testSHJH(){
public void testSHJH() {
Stop stop = new Stop("Stop2323");
BifStop bifStop1 = new BifStop(1, new Stop("Stop2323"));

View file

@ -1,15 +1,18 @@
package fr.u_paris.gla.project.idfm;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.util.Arrays;
import java.util.List;
import org.junit.jupiter.api.Test;
public class TraceEntryTest {
//addTerminus
@Test
public void testAddTerminus() {
TraceEntry traceEntry = new TraceEntry("Ligne 1","IDFM:03434","Bus", "dummy_url");
TraceEntry traceEntry = new TraceEntry("Ligne 1", "IDFM:03434", "Bus", "dummy_url");
String terminus1 = "Terminus A";
String terminus2 = "Terminus B";
@ -19,14 +22,16 @@ public class TraceEntryTest {
List<String> terminusList = traceEntry.getTerminus();
assertEquals(2, terminusList.size(), "La liste des terminus doit contenir deux éléments.");
assertTrue(terminusList.contains(terminus1), "La liste des terminus doit contenir le terminus A.");
assertTrue(terminusList.contains(terminus2), "La liste des terminus doit contenir le terminus B.");
assertTrue(terminusList.contains(terminus1),
"La liste des terminus doit contenir le terminus A.");
assertTrue(terminusList.contains(terminus2),
"La liste des terminus doit contenir le terminus B.");
}
//addPath
@Test
public void testAddPath() {
TraceEntry traceEntry = new TraceEntry("Ligne 1","IDFM:03434","Bus", "dummy_url");
TraceEntry traceEntry = new TraceEntry("Ligne 1", "IDFM:03434", "Bus", "dummy_url");
StopEntry stop1 = new StopEntry("Station 1", 2.300, 48.850);
StopEntry stop2 = new StopEntry("Station 2", 2.310, 48.855);
List<StopEntry> path = Arrays.asList(stop1, stop2);
@ -35,14 +40,15 @@ public class TraceEntryTest {
assertEquals(1, paths.size(), "Il doit y avoir un chemin dans la liste des chemins.");
assertEquals(2, paths.get(0).size(), "Le chemin ajouté doit contenir deux arrêts.");
assertTrue(paths.get(0).containsAll(path), "Le chemin ajouté doit contenir les arrêts spécifiés.");
assertTrue(paths.get(0).containsAll(path),
"Le chemin ajouté doit contenir les arrêts spécifiés.");
}
//Verfier si le nom de la ligne lname est correctement initialiser
@Test
public void testTraceEntryName() {
TraceEntry traceEntry = new TraceEntry("Ligne 1","IDFM:03434","Bus", "dummy_url");
TraceEntry traceEntry = new TraceEntry("Ligne 1", "IDFM:03434", "Bus", "dummy_url");
assertEquals("Ligne 1", traceEntry.lname, "Le nom de la ligne doit être 'Ligne 1'.");
}
}

View file

@ -1,12 +1,10 @@
package fr.u_paris.gla.project.idfm;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
import org.junit.jupiter.api.Test;
import java.util.AbstractMap.SimpleEntry;
import java.util.List;
import java.util.ArrayList;
import static org.junit.jupiter.api.Assertions.*;
public class TransportTest {

View file

@ -1,8 +1,9 @@
package fr.u_paris.gla.project.idfm;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotEquals;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
import org.junit.jupiter.api.Test;
@ -65,20 +66,20 @@ public class UnidentifiedStopEntryTest {
UnidentifiedStopEntry unidentifiedStopEntry2 = new UnidentifiedStopEntry(0, 0);
// Test lorsque nous comparons un UnidentifiedStopEntry avec lui-même
assertTrue(unidentifiedStopEntry1.equals(unidentifiedStopEntry1));
assertEquals(unidentifiedStopEntry1, unidentifiedStopEntry1);
// Test lorsque nous comparons deux UnidentifiedStopEntry qui n'ont pas de candidats
assertTrue(unidentifiedStopEntry1.equals(unidentifiedStopEntry2));
assertEquals(unidentifiedStopEntry1, unidentifiedStopEntry2);
// Test lorsque nous ajoutons le même StopEntry aux deux UnidentifiedStopEntry
StopEntry stopEntry = new StopEntry("Stop1", 10.0, 20.0);
unidentifiedStopEntry1.addCandidate(stopEntry);
unidentifiedStopEntry2.addCandidate(stopEntry);
assertTrue(unidentifiedStopEntry1.equals(unidentifiedStopEntry2));
assertEquals(unidentifiedStopEntry1, unidentifiedStopEntry2);
// Test lorsque nous ajoutons un autre StopEntry à l'un des UnidentifiedStopEntry
StopEntry stopEntry2 = new StopEntry("Stop2", 30.0, 40.0);
unidentifiedStopEntry1.addCandidate(stopEntry2);
assertFalse(unidentifiedStopEntry1.equals(unidentifiedStopEntry2));
assertNotEquals(unidentifiedStopEntry1, unidentifiedStopEntry2);
}
}

View file

@ -1,15 +1,13 @@
package fr.u_paris.gla.project.io;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.text.NumberFormat;
import java.time.Duration;
import java.time.LocalTime;
import java.time.format.DateTimeParseException;
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.Test;
class NetworkFormatTest {
@ -34,7 +32,7 @@ class NetworkFormatTest {
}
@Test
public void parseThenFormatDuration(){
public void parseThenFormatDuration() {
String t = "00:00";
assertEquals(t, NetworkFormat.formatDuration(NetworkFormat.parseDuration(t)));
}
@ -54,6 +52,7 @@ class NetworkFormatTest {
}
@Test
public void getGPSFormatterNul() {
int GPS_nul = 0;
@ -68,13 +67,11 @@ class NetworkFormatTest {
String string_float = "5675747274674276474267479751262167";
BigDecimal GPS_big = new BigDecimal(string_int + "." + string_float);
assertEquals(string_int + "." + string_float.substring(0, NetworkFormat.GPS_PRECISION),
GPS_test.format(GPS_big).replace(",", "").replace(" ",""));
GPS_test.format(GPS_big).replace(",", "").replace(" ", ""));
}
}

View file

@ -1,14 +1,12 @@
package fr.u_paris.gla.project.io;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Arrays;
import java.util.List;
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.Test;
class ScheduleFormatTest {

View file

@ -1,44 +1,37 @@
package fr.u_paris.gla.project.utils;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertThrows;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.UUID;
import java.util.function.Consumer;
import java.util.stream.Stream;
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.Test;
class CSVToolsTest {
@Test
public void readCSVFromURL_invalid() {
// TODO Fix the exception thrown
/**
assertThrows(IOException.class,() -> {
/* assertThrows(IOException.class,() -> {
Consumer<String[]> test = s -> System.out.println(Arrays.toString(s));
CSVTools.readCSVFromURL("https://google.fr",
test);
}
);
*/
); */
}
@Test
public void testreadCSVFromURL_valid() {
public void testReadCSVFromURL_valid() {
assertDoesNotThrow(() -> {
Consumer<String[]> test = s -> System.out.println(Arrays.toString(s));
CSVTools.readCSVFromURL("https://people.sc.fsu.edu/~jburkardt/data/csv/addresses.csv",
test);
}
);
}
@ -77,8 +70,7 @@ class CSVToolsTest {
@Test
void writeCSVToFile_invalidName() {
assertThrows( IOException.class ,() -> {
assertThrows(IOException.class, () -> {
String[] stuff = {"jsqdsqdsqsqffdfgzava", "pfezegrrbeebn", "dfbsduifzegbczi", "sdfsdfcy"};
String[][] t = {stuff, stuff};
Stream<String[]> test = Arrays.stream(t);

View file

@ -1,14 +1,16 @@
package fr.u_paris.gla.project.utils;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotEquals;
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.Test;
class GPSTest {
@Test
public void testDistance_SameLat(){
public void testDistance_SameLat() {
assertDoesNotThrow(
() -> {
GPS.distance(5, 3, 5, 11);
@ -17,7 +19,7 @@ class GPSTest {
}
@Test
public void distance_SameLon(){
public void distance_SameLon() {
assertDoesNotThrow(
() -> {
GPS.distance(5, 3, 7, 3);
@ -27,11 +29,11 @@ class GPSTest {
@Test
public void distance_SamePoint() {
assertEquals(0.0, GPS.distance(5, 3, 5, 3) );
assertEquals(0.0, GPS.distance(5, 3, 5, 3));
}
@Test
public void distance_NegativePoint(){
public void distance_NegativePoint() {
assertNotEquals(0.0, GPS.distance(-5, 7, -13, 4));
}