[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.
- [ ] 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.
## 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,107 +8,123 @@ 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. */
private static final String LOGO_NAME = "uparis_logo_rvb.png"; //$NON-NLS-1$
/** Image height. */
private static final int HEIGHT = 256;
/** Image width. */
private static final int WIDTH = HEIGHT;
/** Resizes an image.
*
* @param src source image
* @param w width
* @param h height
* @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();
g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g2d.drawImage(src, 0, 0, w, h, null);
g2d.dispose();
return resizedImg;
/**
*
*/
private static final String UNSPECIFIED = "Unspecified"; //$NON-NLS-1$
/**
* The logo image name.
*/
private static final String LOGO_NAME = "uparis_logo_rvb.png"; //$NON-NLS-1$
/**
* Image height.
*/
private static final int HEIGHT = 256;
/**
* Image width.
*/
private static final int WIDTH = HEIGHT;
/**
* Resizes an image.
*
* @param src source image
* @param w width
* @param h height
* @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();
g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g2d.drawImage(src, 0, 0, w, h, null);
g2d.dispose();
return resizedImg;
}
/**
* Application entry point.
*
* @param args launching arguments
*/
public static void main(String[] args) {
for (String string : args) {
if ("--info".equals(string)) { //$NON-NLS-1$
printAppInfos(System.out);
return;
}
if ("--gui".equals(string)) { //$NON-NLS-1$
showLogo();
}
}
}
/**
* @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("By: " + props.getProperty("app.team", UNSPECIFIED)); //$NON-NLS-1$ //$NON-NLS-2$
}
private static Properties readApplicationProperties() {
Properties props = new Properties();
try (InputStream is = App.class.getResourceAsStream("application.properties")) { //$NON-NLS-1$
props.load(is);
} catch (IOException e) {
throw new RuntimeException("Unable to read application informations", e); //$NON-NLS-1$
}
return props;
}
/**
* Shows the logo in an image.
*/
public static void showLogo() {
Properties props = readApplicationProperties();
JFrame frame = new JFrame(props.getProperty("app.name")); //$NON-NLS-1$
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
JLabel container = new JLabel();
try (InputStream is = App.class.getResourceAsStream(LOGO_NAME)) {
if (is == null) {
container.setText("Image Not Found");
} else {
BufferedImage img = ImageIO.read(is);
ImageIcon icon = new ImageIcon(img);
ImageIcon resized = new ImageIcon(
getScaledImage(icon.getImage(), WIDTH, HEIGHT));
container.setIcon(resized);
}
} catch (IOException e) {
container.setText("Image Not Read: " + e.getLocalizedMessage());
}
/** Application entry point.
*
* @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);
return;
}
if ("--gui".equals(string)) { //$NON-NLS-1$
showLogo();
}
}
}
}
frame.getContentPane().add(container);
/** @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("By: " + props.getProperty("app.team", UNSPECIFIED)); //$NON-NLS-1$ //$NON-NLS-2$
}
private static Properties readApplicationProperties() {
Properties props = new Properties();
try (InputStream is = App.class.getResourceAsStream("application.properties")) { //$NON-NLS-1$
props.load(is);
} catch (IOException e) {
throw new RuntimeException("Unable to read application informations", e); //$NON-NLS-1$
}
return props;
}
/** Shows the logo in an image. */
public static void showLogo() {
Properties props = readApplicationProperties();
JFrame frame = new JFrame(props.getProperty("app.name")); //$NON-NLS-1$
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
JLabel container = new JLabel();
try (InputStream is = App.class.getResourceAsStream(LOGO_NAME)) {
if (is == null) {
container.setText("Image Not Found");
} else {
BufferedImage img = ImageIO.read(is);
ImageIcon icon = new ImageIcon(img);
ImageIcon resized = new ImageIcon(
getScaledImage(icon.getImage(), WIDTH, HEIGHT));
container.setIcon(resized);
}
} catch (IOException e) {
container.setText("Image Not Read: " + e.getLocalizedMessage());
}
frame.getContentPane().add(container);
frame.pack();
frame.setVisible(true);
}
frame.pack();
frame.setVisible(true);
}
}

View file

@ -1,363 +1,357 @@
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 JMenuItem Favorites;
private JPanel NetworkPanel;
private JTextField TextLocation;
private JButton ButtonLocation;
private JPanel HomePanel;
private JPanel MainPanel;
private DefaultTableModel modelStops;
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 JLabel FavLabel;
private String departureCur;
private JTable tableStops;
private String arrivalCur;
private JTable tableItinerary;
private String searchLocation;
private DefaultTableModel modelItinerary;
private String searchCoord;
private JScrollPane paneStops;
private ArrayList<Stop> searchRes;
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;
private String searchLocation;
private String searchCoord;
private ArrayList<Stop> searchRes;
private int count = 0;
private int count = 0;
public View(ArrayList<Stop> s) throws HeadlessException {
MainPanel = new JPanel();
GridLayout MainLayout = new GridLayout(1, 2, 50, 0);
MainPanel.setLayout(MainLayout);
CardLayout CardLay = new CardLayout();
CardPanel = new JPanel(CardLay);
public View(ArrayList<Stop> s) throws HeadlessException {
MainPanel = new JPanel();
GridLayout MainLayout = new GridLayout(1, 2, 50, 0);
MainPanel.setLayout(MainLayout);
CardLayout CardLay = new CardLayout();
CardPanel = new JPanel(CardLay);
HomePanel = new JPanel();
HomePanel = new JPanel();
CardPanel.add(HomePanel);
SearchCoordPanel = new JPanel();
SearchLocationPanel = new JPanel();
GridLayout SearchLayout = new GridLayout(1, 2);
HomePanel.setLayout(SearchLayout);
HomePanel.add(SearchCoordPanel);
HomePanel.add(SearchLocationPanel);
GridLayout SearchCoordLayout = new GridLayout(2, 1);
GridLayout SearchLocationLayout = new GridLayout(2, 1);
SearchCoordPanel.setLayout(SearchCoordLayout);
SearchLocationPanel.setLayout(SearchLocationLayout);
TextCoord = new JTextField();
ButtonCoord = new JButton("Look for coords");
SearchCoordPanel.add(TextCoord);
SearchCoordPanel.add(ButtonCoord);
TextLocation = new JTextField();
ButtonLocation = new JButton("Look for string");
SearchLocationPanel.add(TextLocation);
SearchLocationPanel.add(ButtonLocation);
NetworkPanel = new JPanel();
CardPanel.add(NetworkPanel);
GridLayout NetworkLayout = new GridLayout(3, 1);
NetworkPanel.setLayout(NetworkLayout);
NetworkLabel = new JLabel("Network");
NetworkPanel.add(NetworkLabel);
stationsPanel = new JPanel();
NetworkPanel.add(stationsPanel);
GridLayout StationsLayout = new GridLayout(2, 1);
departText = new JLabel("Départ: ");
arrText = new JLabel("Arivée: ");
stationsPanel.setLayout(StationsLayout);
stationsPanel.add(departText);
stationsPanel.add(arrText);
paneStops = new JScrollPane();
tableStops = new JTable();
paneStops.add(tableStops);
NetworkPanel.add(paneStops);
ItineraryPanel = new JPanel();
CardPanel.add(ItineraryPanel);
GridLayout ItineraryLayout = new GridLayout(2, 1);
ItineraryPanel.setLayout(ItineraryLayout);
paneItinerary = new JScrollPane();
tableItinerary = new JTable();
paneItinerary.add(tableItinerary);
ItineraryPanel.add(paneItinerary);
ButtonBar = new JMenuBar();
GridLayout ButtonLayout = new GridLayout(3, 1);
ButtonBar.setLayout(ButtonLayout);
Home = new JMenuItem("Home");
ButtonBar.add(Home);
Network = new JMenuItem("Network");
ButtonBar.add(Network);
Itinerary = new JMenuItem("Itinerary");
ButtonBar.add(Itinerary);
ButtonBar.setPreferredSize(new Dimension(50, 500));
MainPanel.add(ButtonBar);
MainPanel.add(CardPanel);
modelStops = (DefaultTableModel) tableStops.getModel();
modelStops.setColumnCount(2);
modelStops.setColumnIdentifiers(new Object[]{"Line", "Stop"});
modelItinerary = (DefaultTableModel) tableItinerary.getModel();
modelItinerary.setColumnCount(3);
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() {
@Override
public void actionPerformed(ActionEvent e) {
CardPanel.removeAll();
CardPanel.add(HomePanel);
SearchCoordPanel = new JPanel();
SearchLocationPanel = new JPanel();
GridLayout SearchLayout = new GridLayout(1, 2);
HomePanel.setLayout(SearchLayout);
HomePanel.add(SearchCoordPanel);
HomePanel.add(SearchLocationPanel);
GridLayout SearchCoordLayout = new GridLayout(2, 1);
GridLayout SearchLocationLayout = new GridLayout(2, 1);
SearchCoordPanel.setLayout(SearchCoordLayout);
SearchLocationPanel.setLayout(SearchLocationLayout);
TextCoord = new JTextField();
ButtonCoord = new JButton("Look for coords");
SearchCoordPanel.add(TextCoord);
SearchCoordPanel.add(ButtonCoord);
TextLocation = new JTextField();
ButtonLocation = new JButton("Look for string");
SearchLocationPanel.add(TextLocation);
SearchLocationPanel.add(ButtonLocation);
CardPanel.repaint();
CardPanel.revalidate();
}
});
NetworkPanel = new JPanel();
Network.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
LoadSearchResult(s, modelStops);
CardPanel.removeAll();
CardPanel.add(NetworkPanel);
GridLayout NetworkLayout = new GridLayout(3, 1);
NetworkPanel.setLayout(NetworkLayout);
NetworkLabel = new JLabel("Network");
NetworkPanel.add(NetworkLabel);
stationsPanel = new JPanel();
NetworkPanel.add(stationsPanel);
GridLayout StationsLayout = new GridLayout(2, 1);
departText = new JLabel("Départ: ");
arrText = new JLabel("Arivée: ");
stationsPanel.setLayout(StationsLayout);
stationsPanel.add(departText);
stationsPanel.add(arrText);
paneStops = new JScrollPane();
tableStops = new JTable();
paneStops.add(tableStops);
NetworkPanel.add(paneStops);
CardPanel.repaint();
CardPanel.revalidate();
}
});
ItineraryPanel = new JPanel();
Itinerary.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
LoadSearchResult(s, modelItinerary);
CardPanel.removeAll();
CardPanel.add(ItineraryPanel);
GridLayout ItineraryLayout = new GridLayout(2, 1);
ItineraryPanel.setLayout(ItineraryLayout);
paneItinerary = new JScrollPane();
tableItinerary = new JTable();
paneItinerary.add(tableItinerary);
ItineraryPanel.add(paneItinerary);
CardPanel.repaint();
CardPanel.revalidate();
}
});
ButtonBar = new JMenuBar();
GridLayout ButtonLayout = new GridLayout(3, 1);
ButtonBar.setLayout(ButtonLayout);
Home = new JMenuItem("Home");
ButtonBar.add(Home);
Network = new JMenuItem("Network");
ButtonBar.add(Network);
TextLocation.addKeyListener(new KeyAdapter() {
@Override
public void keyReleased(KeyEvent e) {
super.keyReleased(e);
if (e.getKeyCode() == KeyEvent.VK_ENTER) {
Itinerary = new JMenuItem("Itinerary");
ButtonBar.add(Itinerary);
ButtonBar.setPreferredSize(new Dimension(50, 500));
searchLocation = TextLocation.getText();
LoadSearchResult(s, modelStops);
System.out.println("Enter key released with text " + searchLocation);
CardPanel.removeAll();
CardPanel.add(NetworkPanel);
MainPanel.add(ButtonBar);
MainPanel.add(CardPanel);
modelStops = (DefaultTableModel) tableStops.getModel();
modelStops.setColumnCount(2);
modelStops.setColumnIdentifiers(new Object[]{"Line", "Stop"});
modelItinerary = (DefaultTableModel) tableItinerary.getModel();
modelItinerary.setColumnCount(3);
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() {
@Override
public void actionPerformed(ActionEvent e) {
CardPanel.removeAll();
CardPanel.add(HomePanel);
CardPanel.repaint();
CardPanel.revalidate();
}
});
Network.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
LoadSearchResult(s, modelStops);
CardPanel.removeAll();
CardPanel.add(NetworkPanel);
CardPanel.repaint();
CardPanel.revalidate();
}
});
Itinerary.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
LoadSearchResult(s, modelItinerary);
CardPanel.removeAll();
CardPanel.add(ItineraryPanel);
CardPanel.repaint();
CardPanel.revalidate();
}
});
TextLocation.addKeyListener(new KeyAdapter() {
@Override
public void keyReleased(KeyEvent e) {
super.keyReleased(e);
if (e.getKeyCode() == KeyEvent.VK_ENTER) {
searchLocation = TextLocation.getText();
LoadSearchResult(s, modelStops);
System.out.println("Enter key released with text " + searchLocation);
CardPanel.removeAll();
CardPanel.add(NetworkPanel);
CardPanel.repaint();
CardPanel.revalidate();
}
}
});
ButtonLocation.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
CardPanel.removeAll();
searchLocation = TextLocation.getText();
LoadSearchResult(s, modelStops);
System.out.println("search location clicked with text " + searchLocation);
CardPanel.add(NetworkPanel);
CardPanel.repaint();
CardPanel.revalidate();
}
});
ButtonCoord.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
CardPanel.removeAll();
searchCoord = TextCoord.getText();
LoadSearchResult(s, modelStops);
System.out.println("search coord clicked with text " + searchCoord);
CardPanel.add(NetworkPanel);
CardPanel.repaint();
CardPanel.revalidate();
}
});
tableStops.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
super.mouseClicked(e);
System.out.println("MouseClick: " + e.getX() + ";" + e.getY());
showOptionsDialog(tableStops, e.getX(), e.getY());
}
});
paneStops.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
super.mouseClicked(e);
}
});
}
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
String stationSel = (String) table.getValueAt(selectedRow, 1);
// 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]);
// Handling the choice
if (choice == 0) {
this.departureCur = stationSel;
this.departText.setText("Departure: " + stationSel);
} else if (choice == 1) {
this.arrivalCur = stationSel;
this.arrText.setText("Arrival: " + stationSel);
} else {
System.out.println("rien");
}
System.out.println("Départ: " + this.departureCur + "; Arrivée: " + this.arrivalCur);
CardPanel.repaint();
CardPanel.revalidate();
}
}
});
ButtonLocation.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
CardPanel.removeAll();
searchLocation = TextLocation.getText();
LoadSearchResult(s, modelStops);
System.out.println("search location clicked with text " + searchLocation);
CardPanel.add(NetworkPanel);
CardPanel.repaint();
CardPanel.revalidate();
}
});
ButtonCoord.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
CardPanel.removeAll();
searchCoord = TextCoord.getText();
LoadSearchResult(s, modelStops);
System.out.println("search coord clicked with text " + searchCoord);
CardPanel.add(NetworkPanel);
CardPanel.repaint();
CardPanel.revalidate();
}
});
tableStops.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
super.mouseClicked(e);
System.out.println("MouseClick: " + e.getX() + ";" + e.getY());
showOptionsDialog(tableStops, e.getX(), e.getY());
}
});
paneStops.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
super.mouseClicked(e);
}
});
}
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
String stationSel = (String) table.getValueAt(selectedRow, 1);
// 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]);
// Handling the choice
if (choice == 0) {
this.departureCur = stationSel;
this.departText.setText("Departure: " + stationSel);
} else if (choice == 1) {
this.arrivalCur = stationSel;
this.arrText.setText("Arrival: " + stationSel);
} else {
System.out.println("rien");
}
System.out.println("Départ: " + this.departureCur + "; Arrivée: " + this.arrivalCur);
}
}
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) {
// 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;
}
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);
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.println();
}
System.out.println(count);
tableStops.revalidate();
tableStops.repaint();
tableItinerary.revalidate();
tableItinerary.repaint();
public void LoadSearchResult(ArrayList<Stop> stops, DefaultTableModel model) {
// Clear existing rows from the table
int cols = model.getColumnCount();
model.setRowCount(0);
model.setColumnCount(cols);
paneStops.setViewportView(tableStops);
paneStops.revalidate();
paneStops.repaint();
paneItinerary.setViewportView(tableItinerary);
paneItinerary.revalidate();
paneItinerary.repaint();
// Add new rows based on the search results
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
NetworkPanel.revalidate();
NetworkPanel.repaint();
model.addRow(new Object[]{String.join(",", stop.getLines()), stop.getName()});
++count;
ItineraryPanel.revalidate();
ItineraryPanel.repaint();
this.displayTableValues(model);
}
public void displayTableValues(TableModel mod) {
for (int row = 0; row < mod.getRowCount(); row++) {
for (int column = 0; column < mod.getColumnCount(); column++) {
if (mod.getValueAt(row, column) != null) {
System.out.print(mod.getValueAt(row, column).toString() + " ");
}
System.out.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();
tableItinerary.revalidate();
tableItinerary.repaint();
paneStops.setViewportView(tableStops);
paneStops.revalidate();
paneStops.repaint();
paneItinerary.setViewportView(tableItinerary);
paneItinerary.revalidate();
paneItinerary.repaint();
NetworkPanel.revalidate();
NetworkPanel.repaint();
ItineraryPanel.revalidate();
ItineraryPanel.repaint();
this.displayTableValues(model);
}
System.out.print(";");
}
System.out.println();
public void displayTableValues(TableModel mod) {
for (int row = 0; row < mod.getRowCount(); row++) {
for (int column = 0; column < mod.getColumnCount(); column++) {
if (mod.getValueAt(row, column) != null) System.out.print(mod.getValueAt(row, column).toString() + " ");
}
System.out.print(";");
}
System.out.println();
}
}
}

View file

@ -1,18 +1,18 @@
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){
bifurc = bif;
this.stop = stop;
}
// The bifurcation
public int bifurc;
public Stop stop;
public BifStop(int bif, Stop stop) {
bifurc = bif;
this.stop = stop;
}
}

View file

@ -3,53 +3,50 @@
*/
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);
private static final NumberFormat MINUTES_SECOND_FORMATTER = NumberFormat
.getInstance(Locale.ENGLISH);
static {
MINUTES_SECOND_FORMATTER.setMinimumIntegerDigits(2);
}
private final String[] line = new String[ImageFormat.NUMBER_COLUMNS];
private final Iterator<Transport> current;
/**
* Create the stream provider
*/
public CSVImageProvider(Iterator<Transport> traces) {
this.current = traces;
}
/**
* Check if next exists
*/
public boolean hasNext() {
return this.current.hasNext();
}
/**
* Get Next element
*/
public String[] next() {
if (!this.hasNext()) {
return null;
}
private final String[] line = new String[ImageFormat.NUMBER_COLUMNS];
private final Iterator<Transport> current;
Transport element = this.current.next();
this.line[ImageFormat.LINE_INDEX] = element.name;
this.line[ImageFormat.IMAGE_URL_INDEX] = element.image_url;
/** Create the stream provider */
public CSVImageProvider(Iterator<Transport> traces) {
this.current = traces;
}
/** Check if next exists */
public boolean hasNext() {
return this.current.hasNext();
}
/** Get Next element */
public String[] next() {
if (!this.hasNext()) {
return null;
}
Transport element = this.current.next();
this.line[ImageFormat.LINE_INDEX] = element.name;
this.line[ImageFormat.IMAGE_URL_INDEX] = element.image_url;
return Arrays.copyOf(this.line, this.line.length);
}
return Arrays.copyOf(this.line, this.line.length);
}
}

View file

@ -1,160 +1,155 @@
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[]>(){{
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});
}};
private static final DateTimeFormatter HOUR_MINUTE_FORMATTER = ScheduleFormat.getTimeFormatter();
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});
}};
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;
// 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);
static {
MINUTES_SECOND_FORMATTER.setMinimumIntegerDigits(2);
}
static {
MINUTES_SECOND_FORMATTER.setMinimumIntegerDigits(2);
private final String[] line = new String[ScheduleFormat.NUMBER_COLUMNS];
private final Iterator<Transport> currentTransport;
private Iterator<TraceDescription> currentDescription = Collections.emptyIterator();
private String current_tansport_type = "";
private LocalDateTime currentHour = null;
private LocalDateTime lastHour = null;
/**
* Create the stream provider
*/
public CSVSchedulesProvider(Iterator<Transport> transports) {
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) {
skipToNextTransport();
} else if (currentHour.isBefore(lastHour)) {
// System.out.println("**Skip: Le current hour est plus petit "+currentHour+"|||"+lastHour);
addRandomMinutes();
} else if (!currentHour.isBefore(lastHour)) {
// System.out.println("**Skip: Le current hour est plus grand "+currentHour+"|||"+lastHour);
skipToNextDescription();
} else if (!this.currentDescription.hasNext()) {
skipToNextTransport();
}
private final String[] line = new String[ScheduleFormat.NUMBER_COLUMNS];
private final Iterator<Transport> currentTransport;
private Iterator<TraceDescription> currentDescription = Collections.emptyIterator();
}
private String current_tansport_type = "";
private LocalDateTime currentHour = null;
private LocalDateTime lastHour = null;
/**
* Move to the the nextDescription of a Transport line
*/
private void skipToNextDescription() {
if (this.currentDescription.hasNext()) {
TraceDescription description = this.currentDescription.next();
currentHour = convertIntoLocalDateTime(description.first);
lastHour = convertIntoLocalDateTime(description.last);
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);
/**
* Create the stream provider
*/
public CSVSchedulesProvider(Iterator<Transport> transports) {
this.currentTransport = transports;
} else {
skipToNextTransport();
}
}
public boolean hasNext() {
return currentTransport.hasNext() || currentDescription.hasNext();
/**
* Move to the next Transport line
*/
private void skipToNextTransport() {
if (this.currentTransport.hasNext()) {
Transport transport = this.currentTransport.next();
this.line[ScheduleFormat.LINE_INDEX] = transport.name;
current_tansport_type = transport.type;
this.currentDescription = transport.descriptions.iterator();
skipToNextDescription();
}
}
private void skipToNext() {
if(currentHour == null || lastHour == null){
skipToNextTransport();
}else if(currentHour.compareTo(lastHour) < 0){
// System.out.println("**Skip: Le current hour est plus petit "+currentHour+"|||"+lastHour);
addRandomMinutes();
}else if (currentHour.compareTo(lastHour) >= 0) {
// System.out.println("**Skip: Le current hour est plus grand "+currentHour+"|||"+lastHour);
skipToNextDescription();
}
else if (!this.currentDescription.hasNext()) {
skipToNextTransport();
}
public String[] next() {
if (!hasNext()) {
return null;
}
skipToNext();
return Arrays.copyOf(this.line, this.line.length);
/**
* Move to the the nextDescription of a Transport line
*/
private void skipToNextDescription() {
if (this.currentDescription.hasNext()) {
TraceDescription description = this.currentDescription.next();
// return new String[][]{Arrays.copyOf(this.line, this.line.length)};
currentHour = convertIntoLocalDateTime(description.first);
lastHour = convertIntoLocalDateTime(description.last);
}
if(lastHour.compareTo(currentHour) <= 0){
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{
skipToNextTransport();
}
}
/**
* Move to the next Transport line
*/
private void skipToNextTransport() {
if (this.currentTransport.hasNext()) {
Transport transport = this.currentTransport.next();
this.line[ScheduleFormat.LINE_INDEX] = transport.name;
current_tansport_type = transport.type;
this.currentDescription = transport.descriptions.iterator();
skipToNextDescription();
}
}
public String[] next() {
if (!hasNext()) {
return null;
}
skipToNext();
return Arrays.copyOf(this.line, this.line.length);
// return new String[][]{Arrays.copyOf(this.line, this.line.length)};
}
/**
* 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);
currentHour = currentHour.plusMinutes(pickMinute(current_tansport_type));
this.line[ScheduleFormat.TIME_INDEX] = currentHour.format(HOUR_MINUTE_FORMATTER);
// System.out.println("** addM: APRES: "+currentHour);
// 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);
}
/**
* 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);
currentHour = currentHour.plusMinutes(pickMinute(current_tansport_type));
this.line[ScheduleFormat.TIME_INDEX] = currentHour.format(HOUR_MINUTE_FORMATTER);
// System.out.println("** addM: APRES: "+currentHour);
// debut ++;
// if(debut == 7) throw new IllegalArgumentException();
}
}

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,285 +18,304 @@ 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>(){{
put("Bus", 0.1);
put("Funicular", 0.1);
put("Tram", 0.1);
put("Rail", 0.2);
put("Subway", 0.1);
}};
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);
put("Rail", 0.2);
put("Subway", 0.1);
}};
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);
put("Rail", 50.0);
put("Subway", 30.0);
}};
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);
put("Rail", 50.0);
put("Subway", 30.0);
}};
/**
* Formatter from numbers into GPS Coordinates
*/
private static final NumberFormat GPS_FORMATTER = NetworkFormat
.getGPSFormatter();
/**
* Formatter from numbers into MM:SS
*/
private static final NumberFormat MINUTES_SECOND_FORMATTER = NumberFormat
.getInstance(Locale.ENGLISH);
static {
MINUTES_SECOND_FORMATTER.setMinimumIntegerDigits(2);
/**
* Formatter from numbers into GPS Coordinates
*/
private static final NumberFormat GPS_FORMATTER = NetworkFormat
.getGPSFormatter();
/**
* Formatter from numbers into MM:SS
*/
private static final NumberFormat MINUTES_SECOND_FORMATTER = NumberFormat
.getInstance(Locale.ENGLISH);
/**
* 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;
/**
* Maximal speed in km/h
*/
private static final double MAX_SPEED = 5;
// 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
*/
private final String[] line = new String[NetworkFormat.NUMBER_COLUMNS];
/**
* 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
*/
private Iterator<List<StopEntry>> currentPath = Collections.emptyIterator();
/**
* current iterator for the begin of the line
*/
private Iterator<StopEntry> currentSegmentStart = Collections.emptyIterator();
/**
* current iterator for the end of the line
*/
private Iterator<StopEntry> currentSegmentEnd = Collections.emptyIterator();
/**
* current begin of line
*/
private StopEntry start = null;
/**
* current end of line
*/
private StopEntry end = null;
/**
* csv stream iterator checker
*/
private boolean hasNext = false;
/**
* tells if we're already on the next
*/
private boolean onNext = false;
private String traceId = "";
private String traceType = "";
private String url_image = "";
/**
* Create the stream provider
*
* @param traces an iterator of the possible traces
* @param t map of transports
*/
public CSVStreamProvider(Iterator<TraceEntry> traces, Map<String, Transport> t) {
this.currentTrace = traces;
transports = t;
}
/**
* 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() {
if (!this.onNext) {
skipToNext();
}
/** 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 */
private static final double MAX_SPEED = 5;
/** Distance to reach maximal speed in km */
private static final double TWO_ACCELERATION_DISTANCE = 0.2;
return this.hasNext;
}
/**
* Current CSV Line
*/
private final String[] line = new String[NetworkFormat.NUMBER_COLUMNS];
/**
* Current CSV transport line iterator
*/
private final Iterator<TraceEntry> currentTrace;
/**
* Current Stop path iterator
*/
private Iterator<List<StopEntry>> currentPath = Collections.emptyIterator();
/**
* current iterator for the begin of the line
*/
private Iterator<StopEntry> currentSegmentStart = Collections.emptyIterator();
/**
* 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
*/
private StopEntry start = null;
/**
* current end of line
*/
private StopEntry end = null;
/**
* csv stream iterator checker
*/
private boolean hasNext = false;
/**
* tells if we're already on the next
*/
private boolean onNext = false;
private String traceId = "";
private String traceType = "";
private String url_image = "";
/** Create the stream provider
* @param traces an iterator of the possible traces
* @param t map of transports */
public CSVStreamProvider(Iterator<TraceEntry> traces, Map<String, Transport> t) {
this.currentTrace = traces;
transports = t;
/**
* Skip to either the next segment or the next path
*/
private void skipToNext() {
if (this.onNext) {
return;
}
while (!this.onNext) {
if (!this.currentSegmentEnd.hasNext()) {
skipToNextCandidatePath();
}
if (this.onNext) {
return;
}
skipToNextNewSegment();
}
}
/** Method that tells if we have segments or paths to go through
* @return if there are next elements or not
*/
public boolean hasNext() {
if (!this.onNext) {
skipToNext();
/**
* Skips to the next segment
*/
private void skipToNextNewSegment() {
do {
this.start = this.currentSegmentStart.next();
this.lineSegments.putIfAbsent(this.start, new HashSet<>());
this.end = this.currentSegmentEnd.next();
} while (this.lineSegments.get(this.start).contains(this.end)
&& this.currentSegmentEnd.hasNext());
if (!this.lineSegments.get(this.start).contains(this.end)) {
this.lineSegments.get(this.start).add(this.end);
this.onNext = true;
this.hasNext = true;
}
}
/**
* Move the reading head of path to the next one that has at least two elements
*/
private void skipToNextCandidatePath() {
currentSegmentStart = null;
do {
while (!this.currentPath.hasNext()) {
if (!this.currentTrace.hasNext()) {
this.hasNext = false;
this.onNext = true;
return;
}
return this.hasNext;
TraceEntry trace = this.currentTrace.next();
this.traceId = trace.id;
this.traceType = trace.type;
this.url_image = trace.url;
this.descriptions.clear();
this.descriptions.addAll(trace.descriptions);
this.currentPath = trace.getPaths().iterator();
this.line[NetworkFormat.LINE_INDEX] = trace.lname;
this.lineSegments.clear();
}
List<StopEntry> path = this.currentPath.next();
this.currentSegmentEnd = path.iterator();
if (this.currentSegmentEnd.hasNext()) {
this.currentSegmentEnd.next();
this.currentSegmentStart = path.iterator();
}
} while (currentSegmentStart == null);
}
// /** 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() {
if (!this.onNext) {
skipToNext();
}
this.onNext = false;
fillStation(this.start, this.line, NetworkFormat.START_INDEX);
fillStation(this.end, this.line, NetworkFormat.STOP_INDEX);
double distance = GPS.distance(this.start.latitude, this.start.longitude,
this.end.latitude, this.end.longitude);
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));
int bifurcation = this.lineSegments.get(this.start).size() - 1;
this.line[NetworkFormat.VARIANT_INDEX] = Integer
.toString(bifurcation);
fillTransports(bifurcation);
return Arrays.copyOf(this.line, this.line.length);
// return new String[][]{Arrays.copyOf(this.line, this.line.length)};
}
private void fillTransports(int bif) {
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);
transports.put(traceId, transp);
} else {
transp = transports.get(traceId);
}
transp.addStop(start_p, end_p, bif);
if (transp.descriptions.isEmpty()) {
transp.addDescriptions(descriptions);
}
}
/**
* Skip to either the next segment or the next path
*/
private void skipToNext() {
if (this.onNext) {
return;
}
while (!this.onNext) {
if (!this.currentSegmentEnd.hasNext()) {
skipToNextCandidatePath();
}
if (this.onNext) {
return;
}
skipToNextNewSegment();
}
}
/**
* Skips to the next segment
*/
private void skipToNextNewSegment() {
do {
this.start = this.currentSegmentStart.next();
this.lineSegments.putIfAbsent(this.start, new HashSet<>());
this.end = this.currentSegmentEnd.next();
} while (this.lineSegments.get(this.start).contains(this.end)
&& this.currentSegmentEnd.hasNext());
if (!this.lineSegments.get(this.start).contains(this.end)) {
this.lineSegments.get(this.start).add(this.end);
this.onNext = true;
this.hasNext = true;
}
}
/** Move the reading head of path to the next one that has at least two
* elements */
private void skipToNextCandidatePath() {
currentSegmentStart = null;
do {
while (!this.currentPath.hasNext()) {
if (!this.currentTrace.hasNext()) {
this.hasNext = false;
this.onNext = true;
return;
}
TraceEntry trace = this.currentTrace.next();
this.traceId = trace.id;
this.traceType = trace.type;
this.url_image = trace.url;
this.descriptions.clear();
this.descriptions.addAll(trace.descriptions);
this.currentPath = trace.getPaths().iterator();
this.line[NetworkFormat.LINE_INDEX] = trace.lname;
this.lineSegments.clear();
}
List<StopEntry> path = this.currentPath.next();
this.currentSegmentEnd = path.iterator();
if (this.currentSegmentEnd.hasNext()) {
this.currentSegmentEnd.next();
this.currentSegmentStart = path.iterator();
}
} while (currentSegmentStart == null);
}
/** Store current trace' data as a String array
* @return The newly generated line of text
*/
public String[] next() {
if (!this.onNext) {
skipToNext();
}
this.onNext = false;
fillStation(this.start, this.line, NetworkFormat.START_INDEX);
fillStation(this.end, this.line, NetworkFormat.STOP_INDEX);
double distance = GPS.distance(this.start.latitude, this.start.longitude,
this.end.latitude, this.end.longitude);
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));
int bifurcation = this.lineSegments.get(this.start).size() - 1;
this.line[NetworkFormat.VARIANT_INDEX] = Integer
.toString(bifurcation);
fillTransports(bifurcation);
return Arrays.copyOf(this.line, this.line.length);
// return new String[][]{Arrays.copyOf(this.line, this.line.length)};
}
/** 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){
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);
transports.put(traceId, transp);
}else{
transp = transports.get(traceId);
}
transp.addStop(start_p, end_p, bif);
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.
@ -25,345 +29,364 @@ import java.util.stream.Stream;
*/
public class IDFMNetworkExtractor {
/**
* The logger for information on the process
*/
private static final Logger LOGGER = Logger
.getLogger(IDFMNetworkExtractor.class.getName());
/**
* The logger for information on the process
*/
private static final Logger LOGGER = Logger
.getLogger(IDFMNetworkExtractor.class.getName());
/**
* the URL of the Trace CSV
*/
// IDF mobilite API URLs
private static final String TRACE_FILE_URL = "https://data.iledefrance-mobilites.fr/api/explore/v2.1/catalog/datasets/traces-des-lignes-de-transport-en-commun-idfm/exports/csv?lang=fr&timezone=Europe%2FBerlin&use_labels=true&delimiter=%3B";
/**
* The URL of the Stops CSV
*/
private static final String STOPS_FILE_URL = "https://data.iledefrance-mobilites.fr/api/explore/v2.1/catalog/datasets/arrets-lignes/exports/csv?lang=fr&timezone=Europe%2FBerlin&use_labels=true&delimiter=%3B";
/**
* the URL of the Trace CSV
*/
// IDF mobilite API URLs
private static final String TRACE_FILE_URL = "https://data.iledefrance-mobilites.fr/api/explore/v2.1/catalog/datasets/traces-des-lignes-de-transport-en-commun-idfm/exports/csv?lang=fr&timezone=Europe%2FBerlin&use_labels=true&delimiter=%3B";
/**
* The URL of the Stops CSV
*/
private static final String STOPS_FILE_URL = "https://data.iledefrance-mobilites.fr/api/explore/v2.1/catalog/datasets/arrets-lignes/exports/csv?lang=fr&timezone=Europe%2FBerlin&use_labels=true&delimiter=%3B";
private static final String TRACE_FILE_DOWNLOADED_NAME = "./trace_idfm.csv";
private static final String STOPS_FILE_DOWNLOADED_NAME = "./arret_idfm.csv";
/**
* the index in the CSV of a Trace's ID
*/
// IDF mobilite csv formats
private static final int IDFM_TRACE_ID_INDEX = 0;
/**
* the index in the CSV of a Trace's Name
*/
private static final int IDFM_TRACE_SNAME_INDEX = 1;
/**
* the index in the CSV of a Trace's shape
*/
private static final int IDFM_TRACE_SHAPE_INDEX = 6;
private static final int IDFM_TRACE_TYPE_INDEX = 3;
private static final String TRACE_FILE_DOWNLOADED_NAME = "./trace_idfm.csv";
private static final String STOPS_FILE_DOWNLOADED_NAME = "./arret_idfm.csv";
/**
* the index in the CSV of a Trace's ID
*/
// IDF mobilite csv formats
private static final int IDFM_TRACE_ID_INDEX = 0;
/**
* the index in the CSV of a Trace's Name
*/
private static final int IDFM_TRACE_SNAME_INDEX = 1;
/**
* the index in the CSV of a Trace's shape
*/
private static final int IDFM_TRACE_SHAPE_INDEX = 6;
private static final int IDFM_TRACE_TYPE_INDEX = 3;
/**
* The index in the CSV of the Stops' id
*/
private static final int IDFM_STOPS_RID_INDEX = 0;
/**
* The index in the CSV of the Stops' schedules
*/
private static final int IDFM_STOPS_SCHEDULES_INDEX = 3;
/**
* The index in the CSV of the Stops' names
*/
private static final int IDFM_STOPS_NAME_INDEX = 5;
/**
* The index in the CSV of the Stops' longitude
*/
private static final int IDFM_STOPS_LON_INDEX = 6;
/**
* The index in the CSV of the Stops' latitude
*/
private static final int IDFM_STOPS_LAT_INDEX = 7;
private static final int IDFM_URL_INDEX = 10;
/**
* The index in the CSV of the Stops' id
*/
private static final int IDFM_STOPS_RID_INDEX = 0;
/**
* The index in the CSV of the Stops' schedules
*/
private static final int IDFM_STOPS_SCHEDULES_INDEX = 3;
/**
* The index in the CSV of the Stops' names
*/
private static final int IDFM_STOPS_NAME_INDEX = 5;
/**
* The index in the CSV of the Stops' longitude
*/
private static final int IDFM_STOPS_LON_INDEX = 6;
/**
* The index in the CSV of the Stops' latitude
*/
private static final int IDFM_STOPS_LAT_INDEX = 7;
private static final int IDFM_URL_INDEX = 10;
private static final String TRACE_FILE_NAME = "trace.csv";
private static final String TRACE_FILE_NAME = "trace.csv";
private static final String HOURS_FILE_NAME = "hours.csv";
private static final String HOURS_FILE_NAME = "hours.csv";
private static final String IMAGES_FILE_NAME = "./images.csv";
private static final String IMAGES_FILE_NAME = "./images.csv";
// Magically chosen values
/**
* A number of stops on each line
*/
private static final int GUESS_STOPS_BY_LINE = 5;
// Magically chosen values
/**
* A number of stops on each line
*/
private static final int GUESS_STOPS_BY_LINE = 5;
/**
* The quarter of a kilometer as a static value
*/
// Well named constants
private static final double QUARTER_KILOMETER = .25;
/**
* The quarter of a kilometer as a static value
*/
// Well named constants
private static final double QUARTER_KILOMETER = .25;
public static boolean checkFileExistence(String filePath) {
File file = new File(filePath);
if (file.exists()) {
LOGGER.severe(filePath+ " already exists.");
return true;
} else {
LOGGER.severe(filePath + " does not exist.");
return false;
}
public static boolean checkFileExistence(String filePath) {
File file = new File(filePath);
if (file.exists()) {
LOGGER.severe(filePath + " already exists.");
return true;
} else {
LOGGER.severe(filePath + " does not exist.");
return false;
}
}
public static void buildFiles() {
if (checkFileExistence("./" + HOURS_FILE_NAME) && checkFileExistence("./" + TRACE_FILE_NAME)) {
LOGGER.severe("Files already exists.");
return;
}
public static void buildFiles() {
if (checkFileExistence("./"+HOURS_FILE_NAME) && checkFileExistence("./"+TRACE_FILE_NAME)) {
LOGGER.severe("Files already exists.");
return;
}
Map<String, TraceEntry> traces = new HashMap<>();
try {
CSVTools.readCSVFromFile(TRACE_FILE_DOWNLOADED_NAME,
(String[] line) -> addLine(line, traces));
} catch (IOException e) {
LOGGER.log(Level.SEVERE, "Error while reading the line paths", e);
}
List<StopEntry> stops = new ArrayList<>(traces.size() * GUESS_STOPS_BY_LINE);
try {
CSVTools.readCSVFromFile(STOPS_FILE_DOWNLOADED_NAME,
(String[] line) -> addStop(line, traces, stops));
} catch (IOException e) {
LOGGER.log(Level.SEVERE, "Error while reading the stops", e);
}
cleanTraces(traces);
Map<String, Transport> transports = new HashMap<>();
CSVStreamProvider provider = new CSVStreamProvider(traces.values().iterator(), transports);
// Write into args[0]
try {
CSVTools.writeCSVToFile(TRACE_FILE_NAME, Stream.iterate(provider.next(),
t -> provider.hasNext(), t -> provider.next()));
} catch (IOException e) {
LOGGER.log(Level.SEVERE, e,
() -> MessageFormat.format("Could not write in file {0}", TRACE_FILE_NAME));
}
System.out.println("******************Building bifurcations ************************");
long startTime = System.currentTimeMillis();
for (Transport entry : transports.values()) {
entry.buildBifurcationOptimzed();
}
long endTime = System.currentTimeMillis();
long tempsPasse = endTime - startTime;
long minutes = (tempsPasse / 1000) / 60;
long seconds = (tempsPasse / 1000) % 60;
long milliseconds = tempsPasse % 1000;
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());
try {
CSVTools.writeCSVToFile(HOURS_FILE_NAME, Stream.iterate(providerschedules.next(),
t -> providerschedules.hasNext(), t -> providerschedules.next()));
} catch (IOException e) {
LOGGER.log(Level.SEVERE, e,
() -> MessageFormat.format("Could not write in file {0}", HOURS_FILE_NAME));
}
CSVImageProvider providerimage = new CSVImageProvider(transports.values().iterator());
try {
CSVTools.writeCSVToFile(IMAGES_FILE_NAME, Stream.iterate(providerimage.next(),
t -> providerimage.hasNext(), t -> providerimage.next()));
} catch (IOException e) {
LOGGER.log(Level.SEVERE, e,
() -> MessageFormat.format("Could not write in file {0}", IMAGES_FILE_NAME));
}
Map<String, TraceEntry> traces = new HashMap<>();
try {
CSVTools.readCSVFromFile(TRACE_FILE_DOWNLOADED_NAME,
(String[] line) -> addLine(line, traces));
} catch (IOException e) {
LOGGER.log(Level.SEVERE, "Error while reading the line paths", e);
}
/** Clean the traces/remove the unresolved lines
* @param traces the traces to clean
*/
private static void cleanTraces(Map<String, TraceEntry> traces) {
Set<String> toRemove = new HashSet<>();
for (Entry<String, TraceEntry> traceEntry : traces.entrySet()) {
TraceEntry trace = traceEntry.getValue();
if (!cleanLine(trace.getPaths())) {
LOGGER.severe(() -> MessageFormat.format(
"Missing stop for line {0}. Line will be removed", trace.lname));
toRemove.add(traceEntry.getKey());
}
}
for (String string : toRemove) {
traces.remove(string);
}
List<StopEntry> stops = new ArrayList<>(traces.size() * GUESS_STOPS_BY_LINE);
try {
CSVTools.readCSVFromFile(STOPS_FILE_DOWNLOADED_NAME,
(String[] line) -> addStop(line, traces, stops));
} catch (IOException e) {
LOGGER.log(Level.SEVERE, "Error while reading the stops", e);
}
/** Tells if the current trasport line has all its stops entries resolved
* @param stops the stops list
* @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++) {
StopEntry stop = path.get(i);
if (!(stop instanceof UnidentifiedStopEntry unidentified)) {
continue;
}
StopEntry stopResolution = unidentified.resolve();
if (stopResolution == null) {
return false;
}
path.set(i, stopResolution);
}
}
return true;
cleanTraces(traces);
Map<String, Transport> transports = new HashMap<>();
CSVStreamProvider provider = new CSVStreamProvider(traces.values().iterator(), transports);
// Write into args[0]
try {
CSVTools.writeCSVToFile(TRACE_FILE_NAME, Stream.iterate(provider.next(),
t -> provider.hasNext(), t -> provider.next()));
} catch (IOException e) {
LOGGER.log(Level.SEVERE, e,
() -> MessageFormat.format("Could not write in file {0}", TRACE_FILE_NAME));
}
/** 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
*/
private static void addStop(String[] line, Map<String, TraceEntry> traces,
List<StopEntry> stops) {
StopEntry entry = new StopEntry(line[IDFM_STOPS_NAME_INDEX],
Double.parseDouble(line[IDFM_STOPS_LON_INDEX]),
Double.parseDouble(line[IDFM_STOPS_LAT_INDEX]));
String rid = line[IDFM_STOPS_RID_INDEX];
System.out.println("******************Building bifurcations ************************");
long startTime = System.currentTimeMillis();
//Add traces description if it's empty
if (traces.containsKey(rid)) {
TraceEntry tmp = traces.get(rid);
if (tmp.isDescriptionEmpty()) {
List<TraceDescription> descriptions = extractDescription(line[IDFM_STOPS_SCHEDULES_INDEX]);
tmp.addDescriptions(descriptions);
}
}
// Add terminus to the traces
if (traces.containsKey(rid)) {
extractTerminus(line[IDFM_STOPS_SCHEDULES_INDEX]).forEach(t -> traces.get(rid).addTerminus(t));
}
traces.computeIfPresent(rid,
(String k, TraceEntry trace) -> addCandidate(trace, entry));
stops.add(entry);
for (Transport entry : transports.values()) {
entry.buildBifurcationOptimzed();
}
/** 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]);
List<List<StopEntry>> buildPaths = buildPaths(line[IDFM_TRACE_SHAPE_INDEX]);
entry.getPaths().addAll(buildPaths);
if (buildPaths.isEmpty()) {
LOGGER.severe(() -> MessageFormat.format(
"Line {0} has no provided itinerary and was ignored", entry.lname));
} else {
traces.put(line[IDFM_TRACE_ID_INDEX], entry);
}
long endTime = System.currentTimeMillis();
long tempsPasse = endTime - startTime;
long minutes = (tempsPasse / 1000) / 60;
long seconds = (tempsPasse / 1000) % 60;
long milliseconds = tempsPasse % 1000;
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());
try {
CSVTools.writeCSVToFile(HOURS_FILE_NAME, Stream.iterate(providerschedules.next(),
t -> providerschedules.hasNext(), t -> providerschedules.next()));
} catch (IOException e) {
LOGGER.log(Level.SEVERE, e,
() -> MessageFormat.format("Could not write in file {0}", HOURS_FILE_NAME));
}
/** add a new entry as a candidate to a trace
* @param trace the trace
* @param entry the entry
* @return the trace in question
*/
private static TraceEntry addCandidate(TraceEntry trace, StopEntry entry) {
for (List<StopEntry> path : trace.getPaths()) {
for (StopEntry stopEntry : path) {
if (stopEntry instanceof UnidentifiedStopEntry unidentified
&& GPS.distance(entry.latitude, entry.longitude,
stopEntry.latitude,
stopEntry.longitude) < QUARTER_KILOMETER) {
unidentified.addCandidate(entry);
}
}
CSVImageProvider providerimage = new CSVImageProvider(transports.values().iterator());
try {
CSVTools.writeCSVToFile(IMAGES_FILE_NAME, Stream.iterate(providerimage.next(),
t -> providerimage.hasNext(), t -> providerimage.next()));
} catch (IOException e) {
LOGGER.log(Level.SEVERE, e,
() -> MessageFormat.format("Could not write in file {0}", IMAGES_FILE_NAME));
}
}
/**
* Clean the traces/remove the unresolved lines
*
* @param traces the traces to clean
*/
private static void cleanTraces(Map<String, TraceEntry> traces) {
Set<String> toRemove = new HashSet<>();
for (Entry<String, TraceEntry> traceEntry : traces.entrySet()) {
TraceEntry trace = traceEntry.getValue();
if (!cleanLine(trace.getPaths())) {
LOGGER.severe(() -> MessageFormat.format(
"Missing stop for line {0}. Line will be removed", trace.lname));
toRemove.add(traceEntry.getKey());
}
}
for (String string : toRemove) {
traces.remove(string);
}
}
/**
* Tells if the current trasport line has all its stops entries resolved
*
* @param stops the stops list
* @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++) {
StopEntry stop = path.get(i);
if (!(stop instanceof UnidentifiedStopEntry unidentified)) {
continue;
}
return trace;
StopEntry stopResolution = unidentified.resolve();
if (stopResolution == null) {
return false;
}
path.set(i, stopResolution);
}
}
return true;
}
/**
* 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
*/
private static void addStop(String[] line, Map<String, TraceEntry> traces,
List<StopEntry> stops) {
StopEntry entry = new StopEntry(line[IDFM_STOPS_NAME_INDEX],
Double.parseDouble(line[IDFM_STOPS_LON_INDEX]),
Double.parseDouble(line[IDFM_STOPS_LAT_INDEX]));
String rid = line[IDFM_STOPS_RID_INDEX];
//Add traces description if it's empty
if (traces.containsKey(rid)) {
TraceEntry tmp = traces.get(rid);
if (tmp.isDescriptionEmpty()) {
List<TraceDescription> descriptions = extractDescription(line[IDFM_STOPS_SCHEDULES_INDEX]);
tmp.addDescriptions(descriptions);
}
}
/** 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
*/
private static List<List<StopEntry>> buildPaths(String pathsJSON) {
List<List<StopEntry>> all = new ArrayList<>();
try {
JSONObject json = new JSONObject(pathsJSON);
JSONArray paths = json.getJSONArray("coordinates");
for (int i = 0; i < paths.length(); i++) {
JSONArray path = paths.getJSONArray(i);
List<StopEntry> stopsPath = new ArrayList<>();
for (int j = 0; j < path.length(); j++) {
JSONArray coordinates = path.getJSONArray(j);
StopEntry entry = new UnidentifiedStopEntry(coordinates.getDouble(0),
coordinates.getDouble(1));
stopsPath.add(entry);
}
all.add(stopsPath);
}
} catch (JSONException e) {
// Ignoring invalid element!
LOGGER.log(Level.FINE, e,
() -> MessageFormat.format("Invalid json element {0}", pathsJSON)); //$NON-NLS-1$
}
return all;
// Add terminus to the traces
if (traces.containsKey(rid)) {
extractTerminus(line[IDFM_STOPS_SCHEDULES_INDEX]).forEach(
t -> traces.get(rid).addTerminus(t));
}
/** extract the terminus out of a JSON file
* @param JSON the JSON
* @return a list of strings related to the terminus
*/
private static List<String> extractTerminus(String JSON) {
List<String> all = new ArrayList<>();
try {
JSONArray schedules = new JSONArray(JSON);
for (int i = 0; i < schedules.length(); i++) {
JSONObject stop = schedules.getJSONObject(i);
String terminus = stop.getString("from");
all.add(terminus);
}
} catch (
traces.computeIfPresent(rid,
(String k, TraceEntry trace) -> addCandidate(trace, entry));
stops.add(entry);
}
JSONException e) {
// Ignoring invalid element!
LOGGER.log(Level.FINE, e,
() -> MessageFormat.format("Invalid json element {0}", JSON)); //$NON-NLS-1$
/**
* 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]);
List<List<StopEntry>> buildPaths = buildPaths(line[IDFM_TRACE_SHAPE_INDEX]);
entry.getPaths().addAll(buildPaths);
if (buildPaths.isEmpty()) {
LOGGER.severe(() -> MessageFormat.format(
"Line {0} has no provided itinerary and was ignored", entry.lname));
} else {
traces.put(line[IDFM_TRACE_ID_INDEX], entry);
}
}
/**
* add a new entry as a candidate to a trace
*
* @param trace the trace
* @param entry the entry
* @return the trace in question
*/
private static TraceEntry addCandidate(TraceEntry trace, StopEntry entry) {
for (List<StopEntry> path : trace.getPaths()) {
for (StopEntry stopEntry : path) {
if (stopEntry instanceof UnidentifiedStopEntry unidentified
&& GPS.distance(entry.latitude, entry.longitude,
stopEntry.latitude,
stopEntry.longitude) < QUARTER_KILOMETER) {
unidentified.addCandidate(entry);
}
}
}
return trace;
}
/**
* 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
*/
private static List<List<StopEntry>> buildPaths(String pathsJSON) {
List<List<StopEntry>> all = new ArrayList<>();
try {
JSONObject json = new JSONObject(pathsJSON);
JSONArray paths = json.getJSONArray("coordinates");
for (int i = 0; i < paths.length(); i++) {
JSONArray path = paths.getJSONArray(i);
List<StopEntry> stopsPath = new ArrayList<>();
for (int j = 0; j < path.length(); j++) {
JSONArray coordinates = path.getJSONArray(j);
StopEntry entry = new UnidentifiedStopEntry(coordinates.getDouble(0),
coordinates.getDouble(1));
stopsPath.add(entry);
}
return all;
all.add(stopsPath);
}
} catch (JSONException e) {
// Ignoring invalid element!
LOGGER.log(Level.FINE, e,
() -> MessageFormat.format("Invalid json element {0}", pathsJSON)); //$NON-NLS-1$
}
return all;
}
/**
* extract the terminus out of a JSON file
*
* @param JSON the JSON
* @return a list of strings related to the terminus
*/
private static List<String> extractTerminus(String JSON) {
List<String> all = new ArrayList<>();
try {
JSONArray schedules = new JSONArray(JSON);
for (int i = 0; i < schedules.length(); i++) {
JSONObject stop = schedules.getJSONObject(i);
String terminus = stop.getString("from");
all.add(terminus);
}
} catch (
JSONException e) {
// Ignoring invalid element!
LOGGER.log(Level.FINE, e,
() -> MessageFormat.format("Invalid json element {0}", JSON)); //$NON-NLS-1$
}
private static List<TraceDescription> extractDescription(String JSON) {
List<TraceDescription> all = new ArrayList<>();
try {
JSONArray schedules = new JSONArray(JSON);
for (int i = 0; i < schedules.length(); i++) {
JSONObject stop = schedules.getJSONObject(i);
String from = stop.getString("from");
String to = stop.getString("to");
String first = stop.getString("first");
String last = stop.getString("last");
//We skip the lines where from equals to
// if(from.compareTo(to) != 0){
all.add(new TraceDescription(from, to, first, last));
// }
}
} catch (JSONException e) {
// Ignoring invalid element!
// e.printStackTrace();
}
return all;
}
return all;
private static List<TraceDescription> extractDescription(String JSON) {
List<TraceDescription> all = new ArrayList<>();
try {
JSONArray schedules = new JSONArray(JSON);
for (int i = 0; i < schedules.length(); i++) {
JSONObject stop = schedules.getJSONObject(i);
String from = stop.getString("from");
String to = stop.getString("to");
String first = stop.getString("first");
String last = stop.getString("last");
//We skip the lines where from equals to
// if(from.compareTo(to) != 0){
all.add(new TraceDescription(from, to, first, last));
// }
}
} catch (JSONException e) {
// Ignoring invalid element!
// e.printStackTrace();
}
return all;
}
}

View file

@ -1,48 +1,49 @@
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;
public String name;
Map<String, BifStop> connected = new HashMap<>();
public Stop(String name){
this.name = 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
*/
public boolean isStopConnected(String stopName) {
return connected.containsKey(stopName);
}
/**
* Checks is stopName is connected to this one
*
* @param stopName
* @return True if stopName is connected to the current stop
*/
public boolean isStopConnected(String stopName) {
return connected.containsKey(stopName);
}
/**
* Add Connected stop
* @param stop connected stop with the bifurcation needed
*/
public void addConnectedStop(BifStop stop) {
connected.put(stop.stop.name, stop);
}
/**
* Add Connected stop
*
* @param stop connected stop with the bifurcation needed
*/
public void addConnectedStop(BifStop stop) {
connected.put(stop.stop.name, stop);
}
/**
* Return the connected stop with the name : stopName
* @param stopName
* @return the connected stop with the name : stopName
*/
public BifStop getConnectedStop(String stopName) {
return connected.get(stopName);
}
/**
* Return the connected stop with the name : stopName
*
* @param stopName
* @return the connected stop with the name : stopName
*/
public BifStop getConnectedStop(String stopName) {
return connected.get(stopName);
}
}

View file

@ -1,5 +1,5 @@
/**
*
*
*/
package fr.u_paris.gla.project.idfm;
@ -7,65 +7,69 @@ import java.text.MessageFormat;
import java.util.Objects;
/** A transport stop data.
*
*
* @author Emmanuel Bigeon */
public class StopEntry implements Comparable<StopEntry> {
public final String lname;
public final double longitude;
public final double latitude;
/** Create the stop
*
* @param lname
* @param longitude
* @param latitude */
public StopEntry(String lname, double longitude, double latitude) {
super();
this.lname = lname;
this.longitude = longitude;
this.latitude = latitude;
}
public final String lname;
public final double longitude;
public final double latitude;
@Override
public String toString() {
return MessageFormat.format("{0} [{1}, {2}]", this.lname, this.longitude, //$NON-NLS-1$
this.latitude);
}
/** Create the stop
*
* @param lname
* @param longitude
* @param latitude */
public StopEntry(String lname, double longitude, double latitude) {
super();
this.lname = lname;
this.longitude = longitude;
this.latitude = latitude;
}
@Override
public int compareTo(StopEntry o) {
if (latitude < o.latitude) {
return -1;
}
if (latitude > o.latitude) {
return 1;
}
if (longitude < o.longitude) {
return -1;
}
if (longitude > o.longitude) {
return 1;
}
return lname.compareTo(o.lname);
}
@Override
public String toString() {
return MessageFormat.format("{0} [{1}, {2}]", this.lname, this.longitude, //$NON-NLS-1$
this.latitude);
}
@Override
public int hashCode() {
return Objects.hash(latitude, lname, longitude);
@Override
public int compareTo(StopEntry o) {
if (latitude < o.latitude) {
return -1;
}
if (latitude > o.latitude) {
return 1;
}
if (longitude < o.longitude) {
return -1;
}
if (longitude > o.longitude) {
return 1;
}
return lname.compareTo(o.lname);
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
StopEntry other = (StopEntry) obj;
return Double.doubleToLongBits(latitude) == Double
.doubleToLongBits(other.latitude) && Objects.equals(lname, other.lname)
&& Double.doubleToLongBits(longitude) == Double
.doubleToLongBits(other.longitude);
}
@Override
public int hashCode() {
return Objects.hash(latitude, lname, longitude);
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
StopEntry other = (StopEntry) obj;
return Double.doubleToLongBits(latitude) == Double
.doubleToLongBits(other.latitude) && Objects.equals(lname, other.lname)
&& Double.doubleToLongBits(longitude) == Double
.doubleToLongBits(other.longitude);
}
}

View file

@ -1,29 +1,31 @@
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){
this.from = from;
this.to = to;
this.first = first;
this.last = last;
}
public String from;
public String to;
public String first;
public String last;
List<Integer> bifurcation = new ArrayList<>();
@Override
public String toString() {
return "From: " + from + ", To: " + to + ", First: " + first + ", Last: " + last + ", Bifurcation: " + bifurcation;
}
public TraceDescription(String from, String to, String first, String last) {
this.from = from;
this.to = to;
this.first = first;
this.last = last;
}
@Override
public String toString() {
return "From: " + from + ", To: " + to + ", First: " + first + ", Last: " + last
+ ", Bifurcation: " + bifurcation;
}
}

View file

@ -12,60 +12,64 @@ 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;
public final String lname;
public final String id;
public final String type;
public final String url;
private final List<String> terminus = new ArrayList<>();
private final List<List<StopEntry>> paths = new ArrayList<>();
List<TraceDescription> descriptions = new ArrayList<>();
private List<String> terminus = new ArrayList<>();
private List<List<StopEntry>> paths = new ArrayList<>();
List <TraceDescription> descriptions = new ArrayList<>();
/**
* Create a transport line.
*
* @param lname the name of the line
*/
public TraceEntry(String lname, String ident, String t_type, String img_url) {
super();
this.lname = lname;
this.id = ident;
this.type = t_type;
this.url = img_url;
}
/**
* Create a transport line.
*
* @param lname the name of the line
*/
public TraceEntry(String lname,String ident,String t_type, String img_url) {
super();
this.lname = lname;
this.id = ident;
this.type = t_type;
this.url = img_url;
}
// FIXME list of lists are bad practice in direct access...
// FIXME list of lists are bad practice in direct access...
/** @return the list of paths */
public List<List<StopEntry>> getPaths() {
// TODO Ne pas retourner directement la liste
return 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 */
public List<String> getTerminus() {
return terminus;
}
/**
* @return the list of terminus
*/
public List<String> getTerminus() {
return terminus;
}
public void addPath(List<StopEntry> path) {
paths.add(new ArrayList<>(path));
}
public void addPath(List<StopEntry> path) {
paths.add(new ArrayList<>(path));
}
public void addTerminus(String term) {
terminus.add(term);
}
public void addTerminus(String term) {
terminus.add(term);
}
public boolean isDescriptionEmpty(){
return descriptions.isEmpty();
}
public boolean isDescriptionEmpty() {
return descriptions.isEmpty();
}
/**
* Add all the description to the current one
* @param desctipt
*/
public void addDescriptions(List<TraceDescription> desctipt){
descriptions.addAll(desctipt);
}
/**
* Add all the description to the current one
*
* @param desctipt
*/
public void addDescriptions(List<TraceDescription> desctipt) {
descriptions.addAll(desctipt);
}
}

View file

@ -1,226 +1,232 @@
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 line descriptions (directions and schedules)
List <TraceDescription> descriptions = new ArrayList<>();
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<>();
public Transport(String name,String type, String url){
this.name = name;
this.type = type;
this.image_url = url;
public Transport(String name, String type, String url) {
this.name = name;
this.type = type;
this.image_url = url;
}
/**
* Build the bifurcation for all the descriptions
*/
public void buildBifurcation() {
// int found = 0;
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>());
if (sol.getKey()) {
// found++;
d.bifurcation = sol.getValue();
}
}
}
// System.out.println("J'en ai trouvé "+found);
}
/**
* Build the bifurcation for all the descriptions
*/
public void buildBifurcation(){
// int found = 0;
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>());
if (sol.getKey()) {
// found++;
d.bifurcation = sol.getValue();
}
}
/**
* Build the bifurcation for all the descriptions but optimized
*/
public void buildBifurcationOptimzed() {
// int found = 0;
for (TraceDescription d : descriptions) {
Stop debut = stopsMap.get(d.from);
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>());
if (sol.getKey()) {
// found++;
d.bifurcation = sol.getValue();
}
// System.out.println("J'en ai trouvé "+found);
}
}
// System.out.println("J'en ai trouvé " + found);
}
/**
* Build the bifurcation for all the descriptions but optimized
*/
public void buildBifurcationOptimzed() {
// int found = 0;
for (TraceDescription d : descriptions) {
Stop debut = stopsMap.get(d.from);
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>());
if (sol.getKey()) {
// found++;
d.bifurcation = sol.getValue();
}
}
}
// System.out.println("J'en ai trouvé " + found);
}
/**
* 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))
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
*/
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);
}
//Checker if the current stop is the bad terminus
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<Integer> bifCopy = new ArrayList<>(bifurcation);
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()){
trouve = true;
bifSol = se.getValue();
}
}
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
*/
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);
}
// Checker if the current stop is the bad terminus
if (isTerminus(currentStop)) {
return new SimpleEntry<>(false, null);
}
alreadyVisited.add(currentStop);
Stop current = stopsMap.get(currentStop);
List<SimpleEntry<Boolean, List<Integer>>> solutions = new ArrayList<>();
for (BifStop b : current.connected.values()) {
if (!alreadyVisited.contains(b.stop.name)) {
List<Integer> bifCopy = new ArrayList<>(bifurcation);
if (b.bifurc != 0) {
bifCopy.add(b.bifurc);
}
solutions.add(roadToLastOptimized(b.stop.name, last, alreadyVisited, 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()) {
trouve = true;
bifSol = se.getValue();
break; // Exit loop if a solution is found
}
}
alreadyVisited.remove(currentStop); // Remove current stop from visited after processing
return new SimpleEntry<>(trouve, bifSol);
}
/**
* 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){
Stop startStop = stopsMap.computeIfAbsent(start, Stop::new);
Stop endStop = stopsMap.computeIfAbsent(end, Stop::new);
BifStop connectedStop = new BifStop(bifurcation, endStop);
startStop.addConnectedStop(connectedStop);
}
/**
* Print every stops of the line and its connections
*/
public void printAllConnectionStops() {
System.out.println("Affichage des couples (stop, next du stop):");
for (Map.Entry<String, Stop> entry : stopsMap.entrySet()) {
Stop stop = entry.getValue();
System.out.println("Stop: " + stop.name);
System.out.println("Next:");
for (BifStop nextEntry : stop.connected.values()) {
System.out.println(nextEntry.bifurc + ": " + nextEntry.stop.name);
}
/**
* 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)) {
return true;
}
}
return false;
}
/**
* Add all the description to the current one
* @param desctipt
*/
public void addDescriptions(List<TraceDescription> desctipt){
descriptions.addAll(desctipt);
/**
* 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
*/
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);
}
//Checker if the current stop is the bad terminus
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<Integer> bifCopy = new ArrayList<>(bifurcation);
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()) {
trouve = true;
bifSol = se.getValue();
}
}
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
*/
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);
}
// Checker if the current stop is the bad terminus
if (isTerminus(currentStop)) {
return new SimpleEntry<>(false, null);
}
alreadyVisited.add(currentStop);
Stop current = stopsMap.get(currentStop);
List<SimpleEntry<Boolean, List<Integer>>> solutions = new ArrayList<>();
for (BifStop b : current.connected.values()) {
if (!alreadyVisited.contains(b.stop.name)) {
List<Integer> bifCopy = new ArrayList<>(bifurcation);
if (b.bifurc != 0) {
bifCopy.add(b.bifurc);
}
solutions.add(roadToLastOptimized(b.stop.name, last, alreadyVisited, 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()) {
trouve = true;
bifSol = se.getValue();
break; // Exit loop if a solution is found
}
}
alreadyVisited.remove(currentStop); // Remove current stop from visited after processing
return new SimpleEntry<>(trouve, bifSol);
}
/**
* 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) {
Stop startStop = stopsMap.computeIfAbsent(start, Stop::new);
Stop endStop = stopsMap.computeIfAbsent(end, Stop::new);
BifStop connectedStop = new BifStop(bifurcation, endStop);
startStop.addConnectedStop(connectedStop);
}
/**
* Print every stops of the line and its connections
*/
public void printAllConnectionStops() {
System.out.println("Affichage des couples (stop, next du stop):");
for (Map.Entry<String, Stop> entry : stopsMap.entrySet()) {
Stop stop = entry.getValue();
System.out.println("Stop: " + stop.name);
System.out.println("Next:");
for (BifStop nextEntry : stop.connected.values()) {
System.out.println(nextEntry.bifurc + ": " + nextEntry.stop.name);
}
}
}
/**
* Add all the description to the current one
*
* @param desctipt
*/
public void addDescriptions(List<TraceDescription> desctipt) {
descriptions.addAll(desctipt);
}
}

View file

@ -1,8 +1,9 @@
/**
*
*
*/
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,63 +11,72 @@ 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.
*
* @author Emmanuel Bigeon */
/**
* A transport stop with unidentified name and potential candidates as to their real value.
*
* @author Emmanuel Bigeon
*/
public final class UnidentifiedStopEntry extends StopEntry {
private List<StopEntry> candidates = new ArrayList<>();
/** Create the stop
*
* @param longitude
* @param latitude */
public UnidentifiedStopEntry(double longitude, double latitude) {
super("Unidentified", longitude, latitude); //$NON-NLS-1$
private final List<StopEntry> candidates = new ArrayList<>();
/**
* Create the stop
*
* @param longitude
* @param latitude
*/
public UnidentifiedStopEntry(double longitude, double latitude) {
super("Unidentified", longitude, latitude); //$NON-NLS-1$
}
@Override
public String toString() {
return MessageFormat.format("UnidentifiedStop [candidates={0}]", this.candidates); //$NON-NLS-1$
}
/**
* Get the most likely choice for the stop
*
* @return the most likely candidate
*/
public StopEntry resolve() {
if (candidates.isEmpty()) {
return null;
}
@Override
public String toString() {
return MessageFormat.format("UnidentifiedStop [candidates={0}]", this.candidates); //$NON-NLS-1$
if (candidates.size() == 1) {
return candidates.get(0);
}
Collections.sort(candidates, (Comparator<? super StopEntry>) (StopEntry s1,
StopEntry s2) -> (int) Math.signum((GPS.distance(latitude, longitude,
s1.latitude, s1.longitude)
- GPS.distance(latitude, longitude, s2.latitude, s2.longitude))));
/** Get the most likely choice for the stop
*
* @return the most likely candidate */
public StopEntry resolve() {
if (candidates.isEmpty()) {
return null;
}
if (candidates.size() == 1) {
return candidates.get(0);
}
Collections.sort(candidates, (Comparator<? super StopEntry>) (StopEntry s1,
StopEntry s2) -> (int) Math.signum((GPS.distance(latitude, longitude,
s1.latitude, s1.longitude)
- GPS.distance(latitude, longitude, s2.latitude, s2.longitude))));
return candidates.get(0);
}
return candidates.get(0);
/**
* Add a candidate.
*
* @param entry the candidate
*/
public void addCandidate(StopEntry entry) {
candidates.add(entry);
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
/** Add a candidate.
*
* @param entry the candidate */
public void addCandidate(StopEntry entry) {
candidates.add(entry);
if (!super.equals(obj)) {
return false;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (!super.equals(obj))
return false;
if (getClass() != obj.getClass())
return false;
UnidentifiedStopEntry other = (UnidentifiedStopEntry) obj;
return Objects.equals(candidates, other.candidates);
if (getClass() != obj.getClass()) {
return false;
}
UnidentifiedStopEntry other = (UnidentifiedStopEntry) obj;
return Objects.equals(candidates, other.candidates);
}
}

View file

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

View file

@ -1,5 +1,5 @@
/**
*
*
*/
package fr.u_paris.gla.project.io;
@ -11,66 +11,68 @@ import java.time.temporal.Temporal;
import java.util.Locale;
/** Definition of the formats of files for this project.
*
*
* @author Emmanuel Bigeon */
public final class NetworkFormat {
/** The amount of columns in the CSV file */
public static final int NUMBER_COLUMNS = 8;
/** The amount of decimal places in the GPS' coordinates */
public static final int GPS_PRECISION = 18;
/** The amount of columns in the CSV file */
public static final int NUMBER_COLUMNS = 8;
/** The index of the line name in the network format */
public static final int LINE_INDEX = 0;
/** The index of the variant number of the segment in the network format */
public static final int VARIANT_INDEX = 1;
/** The index of the segment trip duration in the network format */
public static final int DURATION_INDEX = 6;
/** The index of the segment distance in the network format */
public static final int DISTANCE_INDEX = 7;
/** The index of the segment end stop name in the network format */
public static final int STOP_INDEX = 4;
/** The index of the segment starting stop name in the network format */
public static final int START_INDEX = 2;
/** The amount of decimal places in the GPS' coordinates */
public static final int GPS_PRECISION = 18;
private static final DateTimeFormatter DURATION_FORMATTER = DateTimeFormatter
.ofPattern("HH:mm:ss");
private static final NumberFormat DURATION_INDIVIDUAL_FORMATTER = NumberFormat
.getIntegerInstance(Locale.ENGLISH);
static {
DURATION_INDIVIDUAL_FORMATTER.setMinimumIntegerDigits(2);
}
private static final Temporal ZERO = LocalTime.parse("00:00:00");
/** The index of the line name in the network format */
public static final int LINE_INDEX = 0;
/** The index of the variant number of the segment in the network format */
public static final int VARIANT_INDEX = 1;
/** The index of the segment trip duration in the network format */
public static final int DURATION_INDEX = 6;
/** The index of the segment distance in the network format */
public static final int DISTANCE_INDEX = 7;
/** The index of the segment end stop name in the network format */
public static final int STOP_INDEX = 4;
/** The index of the segment starting stop name in the network format */
public static final int START_INDEX = 2;
/** Hidden constructor for utility class */
private NetworkFormat() {
// Tool class
}
private static final DateTimeFormatter DURATION_FORMATTER = DateTimeFormatter
.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");
/** Convert a {@link java.lang.String} into a {@link java.time.Duration}
* @param duration the {@link java.lang.String}
* @return the {@link java.time.Duration} object
*/
public static Duration parseDuration(String duration) {
LocalTime time = LocalTime.parse("00:" + duration, DURATION_FORMATTER);
return Duration.between(time, ZERO);
}
static {
DURATION_INDIVIDUAL_FORMATTER.setMinimumIntegerDigits(2);
}
/** Format a {@link java.time.Duration} into a {@link java.lang.String}
* @param duration an object of type {@link java.time.Duration}
* @return a String that depicts the duration in format MM:SS
*/
public static String formatDuration(Duration duration) {
return DURATION_INDIVIDUAL_FORMATTER.format(duration.toMinutes()) + ":"
+ DURATION_INDIVIDUAL_FORMATTER.format(duration.toSecondsPart());
}
/** Hidden constructor for utility class */
private NetworkFormat() {
// Tool class
}
/** Get a formatter for the numbers in a GPS coordinate pair
*
* @return the {@link java.text.NumberFormat} formatter for numbers in a GPS coordinate pair */
public static NumberFormat getGPSFormatter() {
NumberFormat instance = NumberFormat.getNumberInstance(Locale.ENGLISH);
instance.setMaximumFractionDigits(GPS_PRECISION);
return instance;
}
/** Convert a {@link java.lang.String} into a {@link java.time.Duration}
* @param duration the {@link java.lang.String}
* @return the {@link java.time.Duration} object
*/
public static Duration parseDuration(String duration) {
LocalTime time = LocalTime.parse("00:" + duration, DURATION_FORMATTER);
return Duration.between(time, ZERO);
}
/** Format a {@link java.time.Duration} into a {@link java.lang.String}
* @param duration an object of type {@link java.time.Duration}
* @return a String that depicts the duration in format MM:SS
*/
public static String formatDuration(Duration duration) {
return DURATION_INDIVIDUAL_FORMATTER.format(duration.toMinutes()) + ":"
+ DURATION_INDIVIDUAL_FORMATTER.format(duration.toSecondsPart());
}
/** Get a formatter for the numbers in a GPS coordinate pair
*
* @return the {@link java.text.NumberFormat} formatter for numbers in a GPS coordinate pair */
public static NumberFormat getGPSFormatter() {
NumberFormat instance = NumberFormat.getNumberInstance(Locale.ENGLISH);
instance.setMaximumFractionDigits(GPS_PRECISION);
return instance;
}
}

View file

@ -14,42 +14,58 @@ import java.util.List;
* @author Emmanuel Bigeon
*/
public final class ScheduleFormat {
/** 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 */
public static final int LINE_INDEX = 0;
/** 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 */
public static final int TERMINUS_INDEX = 2;
/** The index of the time in the schedule format */
public static final int TIME_INDEX = 3;
/**
* The amount of columns in the CSV file
*/
public static final int NUMBER_COLUMNS = 4;
/** Hidden constructor for tool class */
private ScheduleFormat() {
// Tool class
}
/**
* 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
*/
public static final int TRIP_SEQUENCE_INDEX = 1;
/**
* 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
*/
public static final int TIME_INDEX = 3;
/**
* Read a trip sequence from its string representation
*
* @param representation the representation
* @return the sequence of branching
*/
public static List<Integer> getTripSequence(String representation) {
/**
* Hidden constructor for tool class
*/
private ScheduleFormat() {
// Tool class
}
List<Integer> l = new ArrayList<>();
for(String s : representation.split(","))
l.add(Integer.parseInt(s));
return l;
}
/**
* Read a trip sequence from its string representation
*
* @param representation the representation
* @return the sequence of branching
*/
public static List<Integer> getTripSequence(String representation) {
List<Integer> l = new ArrayList<>();
for (String s : representation.split(",")) {
l.add(Integer.parseInt(s));
}
return l;
}
/** Create a {@link java.time.format.DateTimeFormatter} object used to format Dates
* @return the formatter
*/
public static DateTimeFormatter getTimeFormatter() {
return DateTimeFormatter.ofPattern("HH:mm").withResolverStyle(ResolverStyle.LENIENT);
}
/**
* Create a {@link java.time.format.DateTimeFormatter} object used to format Dates
*
* @return the formatter
*/
public static DateTimeFormatter getTimeFormatter() {
return DateTimeFormatter.ofPattern("HH:mm").withResolverStyle(ResolverStyle.LENIENT);
}
}

View file

@ -3,97 +3,100 @@ package fr.u_paris.gla.project.itinerary;
import java.util.ArrayList;
import java.util.Collections;
public class Connection{
// Destination of the connection between the two stops
private final Stop stop;
public class Connection {
// The line used for this connection
private final String lineName;
// Destination of the connection between the two stops
private final Stop stop;
//Distance between the two stops
private final double distance;
// The line used for this connection
private final String lineName;
//Travel time between the two stops
private final int time;
//Distance between the two stops
private final double distance;
private final ArrayList<Integer> schedules;
//Travel time between the two stops
private final int time;
private final int bifurcation;
private final ArrayList<Integer> schedules;
public Connection(Stop stop, String lineName, double distance, int time, int bifurcation){
this.stop = stop;
this.lineName=lineName;
this.distance = distance;
this.time = time;
this.schedules = new ArrayList<>();
this.bifurcation = bifurcation;
private final int bifurcation;
public Connection(Stop stop, String lineName, double distance, int time, int bifurcation) {
this.stop = stop;
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) {
this(stop, lineName, distance, time, 0);
}
public String getLineName() {
return lineName;
}
public double getDistance() {
return distance;
}
public int getTime() {
return time;
}
public Stop getStop() {
return stop;
}
public void addSchedule(int hours) {
this.schedules.add(hours);
}
public void sortSchedule() {
Collections.sort(this.schedules);
}
public ArrayList<Integer> getSchedules() {
return this.schedules;
}
public int getBifurcation() {
return this.bifurcation;
}
public double getCost() {
return this.time;
}
public double getNextTime(double currentTime) {
if (this.schedules.size() == 0) {
return currentTime;
}
public Connection(Stop stop, String lineName, double distance, int time){
this(stop, lineName, distance, time, 0);
int i = 0;
while (i < this.schedules.size() && this.schedules.get(i) < currentTime) {
i++;
}
public String getLineName() {
return lineName;
if (i < this.schedules.size()) {
return this.schedules.get(i);
}
return this.schedules.get(0);
}
public double getDistance() {
return distance;
}
public int getTime() {
return time;
}
public Stop getStop() {
return stop;
}
public void addSchedule(int hours) {
this.schedules.add(hours);
}
public void sortSchedule() {
Collections.sort(this.schedules);
}
public ArrayList<Integer> getSchedules() {
return this.schedules;
}
public int getBifurcation() {
return this.bifurcation;
}
public double getCost() {
public double getCost(double currentTime) {
if (this.schedules.size() == 0) {
if (this.lineName.equals("WALK")) {
return this.time;
}
return this.time + 900;
}
public double getNextTime(double currentTime) {
if(this.schedules.size() == 0) {
return currentTime;
}
int i = 0;
while(i < this.schedules.size() && this.schedules.get(i) < currentTime) {
i++;
}
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")) {
return this.time;
}
return this.time + 900;
}
double nextTime = this.getNextTime(currentTime);
if(nextTime < currentTime) { nextTime += 86400;}
return nextTime - currentTime + this.time;
double nextTime = this.getNextTime(currentTime);
if (nextTime < currentTime) {
nextTime += 86400;
}
return nextTime - currentTime + this.time;
}
}

View file

@ -1,116 +1,125 @@
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 {
public class Finder {
private Graph graph;
public Finder(Graph graph) {
this.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
*/
public List<Path> findPath(Stop startNode, Stop goalNode, double startTime) {
PriorityQueue<Stop> openSet = new PriorityQueue<>(Comparator.comparingDouble(GraphNode::getF));
HashSet<Stop> closedSet = new HashSet<>();
HashMap<Stop, Path> cameFrom = new HashMap<>();
HashMap<Stop, Double> gScore = new HashMap<>();
HashMap<Stop, Double> fScore = new HashMap<>();
// Initialize scores for all nodes to infinity
for (Stop node : graph.getNodes()) {
gScore.put(node, Double.POSITIVE_INFINITY);
fScore.put(node, Double.POSITIVE_INFINITY);
}
/**
* return a path from startNode to goalNode using A* algorithm
* @param startNode
* @param goalNode
*/
public List<Path> findPath(Stop startNode, Stop goalNode, double startTime) {
// The cost of going from start to start is the start time
gScore.put(startNode, startTime);
// For the first node, fScore = gScore + heuristic
fScore.put(startNode, startNode.getHeuristicCost(goalNode));
openSet.add(startNode);
PriorityQueue<Stop> openSet = new PriorityQueue<>(Comparator.comparingDouble(GraphNode::getF));
HashSet<Stop> closedSet = new HashSet<>();
HashMap<Stop, Path> cameFrom = new HashMap<>();
HashMap<Stop, Double> gScore = new HashMap<>();
HashMap<Stop, Double> fScore = new HashMap<>();
while (!openSet.isEmpty()) {
Stop current = openSet.poll();
double currentTime = gScore.get(current);
// Initialize scores for all nodes to infinity
for (Stop node : graph.getNodes()) {
gScore.put(node, Double.POSITIVE_INFINITY);
fScore.put(node, Double.POSITIVE_INFINITY);
if (current.equals(goalNode)) {
return reconstructPath(cameFrom, current);
}
closedSet.add(current);
if (graph.getConnections(current) == null) {
continue;
}
for (Connection connection : graph.getConnections(current)) {
Stop neighbor = connection.getStop();
if (closedSet.contains(neighbor)) {
continue; // Ignore the neighbor which is already evaluated.
}
// The cost of going from start to start is the start time
gScore.put(startNode, startTime);
// For the first node, fScore = gScore + heuristic
fScore.put(startNode, startNode.getHeuristicCost(goalNode));
openSet.add(startNode);
double tentativeGScore = currentTime + connection.getCost(currentTime);
while (!openSet.isEmpty()) {
Stop current = openSet.poll();
double currentTime = gScore.get(current);
if (current.equals(goalNode)) {
return reconstructPath(cameFrom, current);
}
closedSet.add(current);
if(graph.getConnections(current) == null) {
continue;
}
for (Connection connection : graph.getConnections(current)) {
Stop neighbor = connection.getStop();
if (closedSet.contains(neighbor)) {
continue; // Ignore the neighbor which is already evaluated.
}
double tentativeGScore = currentTime + connection.getCost(currentTime);
if (tentativeGScore >= gScore.get(neighbor)) {
continue; // This is not a better path.
}
// This path is the best until now. Record it!
cameFrom.put(neighbor, new Path(current, connection, currentTime));
gScore.put(neighbor, tentativeGScore);
fScore.put(neighbor, tentativeGScore + neighbor.getHeuristicCost(goalNode));
if (!openSet.contains(neighbor)) {
neighbor.setF(fScore.get(neighbor));
openSet.add(neighbor);
}
else {
updatePriority(openSet, neighbor, fScore.get(neighbor));
}
}
if (tentativeGScore >= gScore.get(neighbor)) {
continue; // This is not a better path.
}
// If we reach here, it means there's no path from start to goal
return null;
}
// This path is the best until now. Record it!
cameFrom.put(neighbor, new Path(current, connection, currentTime));
gScore.put(neighbor, tentativeGScore);
fScore.put(neighbor, tentativeGScore + neighbor.getHeuristicCost(goalNode));
/**
* Once we found the destination we reconstruct the path
* @param cameFrom
* @param current
* @return path
*/
private List<Path> reconstructPath(HashMap<Stop, Path> cameFrom, Stop current) {
List<Path> totalPath = new ArrayList<>();
totalPath.add(cameFrom.get(current));
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 (!openSet.contains(neighbor)) {
neighbor.setF(fScore.get(neighbor));
openSet.add(neighbor);
} else {
updatePriority(openSet, neighbor, fScore.get(neighbor));
}
return totalPath;
}
}
/**
* Update the priority queue
* @param openSet
* @param node
* @param newF
*/
public void updatePriority(PriorityQueue<Stop> openSet, Stop node, double newF) {
openSet.remove(node);
node.setF(newF);
openSet.add(node);
// If we reach here, it means there's no path from start to goal
return null;
}
/**
* Once we found the destination we reconstruct the path
*
* @param cameFrom
* @param current
* @return path
*/
private List<Path> reconstructPath(HashMap<Stop, Path> cameFrom, Stop current) {
List<Path> totalPath = new ArrayList<>();
totalPath.add(cameFrom.get(current));
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
}
}
return totalPath;
}
/**
* Update the priority queue
*
* @param openSet
* @param node
* @param newF
*/
public void updatePriority(PriorityQueue<Stop> openSet, Stop node, double newF) {
openSet.remove(node);
node.setF(newF);
openSet.add(node);
}
}

View file

@ -1,28 +1,28 @@
package fr.u_paris.gla.project.itinerary;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class Graph{
private final Set<Stop> nodes;
public class Graph {
private final Map<Stop, Set<Connection>> connections;
private final Set<Stop> nodes;
public Graph(Set<Stop> nodes, Map<Stop, Set<Connection>> connections) {
this.nodes = nodes;
this.connections = connections;
}
private final Map<Stop, Set<Connection>> connections;
public Set<Connection> getConnections(Stop node) {
return connections.get(node);
}
public Graph(Set<Stop> nodes, Map<Stop, Set<Connection>> connections) {
this.nodes = nodes;
this.connections = connections;
}
public Set<Stop> getNodes() {
return nodes;
}
public Set<Connection> getConnections(Stop node) {
return connections.get(node);
}
public Map<Stop, Set<Connection>> getConnections() {
return connections;
}
public Set<Stop> getNodes() {
return nodes;
}
public Map<Stop, Set<Connection>> getConnections() {
return 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);
int getId();
double getHeuristicCost(Stop goalNode);
Set<Stop> getNeighbors();
double getCost(Stop neighbor);
double getF();
void setF(double value);
}

View file

@ -1,241 +1,266 @@
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());
// IDF mobilite generated file
private static final String TRACE_FILE_NAME = "./trace.csv";
private static final Logger LOGGER = Logger
.getLogger(IDFMNetworkExtractor.class.getName());
private static final String HOURS_FILE_NAME = "./hours.csv";
// IDF mobilite generated file
private static final String TRACE_FILE_NAME = "./trace.csv";
// IDF mobilite file format
private static final String HOURS_FILE_NAME = "./hours.csv";
private static final int IDFM_TRACE_ID_INDEX = 0;
// IDF mobilite file format
private static final int IDFM_TRACE_DERIV_INDEX = 1;
private static final int IDFM_TRACE_ID_INDEX = 0;
private static final int IDFM_TRACE_FROM_INDEX = 2;
private static final int IDFM_TRACE_DERIV_INDEX = 1;
private static final int IDFM_TRACE_FROM_GPS_INDEX = 3;
private static final int IDFM_TRACE_FROM_INDEX = 2;
private static final int IDFM_TRACE_TO_INDEX= 4;
private static final int IDFM_TRACE_FROM_GPS_INDEX = 3;
private static final int IDFM_TRACE_TO_GPS_INDEX = 5;
private static final int IDFM_TRACE_TO_INDEX = 4;
private static final int IDFM_TRACE_TIME_INDEX = 6;
private static final int IDFM_TRACE_TO_GPS_INDEX = 5;
private static final int IDFM_TRACE_DISTANCE_INDEX = 7;
private static final int IDFM_TRACE_TIME_INDEX = 6;
private static final double ERROR_MARGIN = 1.;
private static final int IDFM_TRACE_DISTANCE_INDEX = 7;
//The time public vehicles spend at each stop in seconds.
private static final int STOP_TIME = 30;
private static final double ERROR_MARGIN = 1.;
//Walking speed in m/s
private static final double WALK_SPEED = 1.;
//The time public vehicles spend at each stop in seconds.
private static final int STOP_TIME = 30;
private HashSet<Stop> nodes = new HashSet<>();
private HashMap<Stop, Set<Connection>> connections = new HashMap<>();
private HashMap<String, ArrayList<Stop>> tmp = new HashMap<>();
//Walking speed in m/s
private static final double WALK_SPEED = 1.;
/**
* 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])};
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}
*
* @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])};
}
/**
* 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
* @param gps the coordinate of the stop
* @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) {
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) {
double dist = GPS.distance(coords[0], coords[1], stop.getLatitude(), stop.getLongitude());
if (dist == 0) {
stop.addLine(lineId);
return stop;
}
if (dist < ERROR_MARGIN) {
lineChanges.add(stop);
}
}
}
/**
* 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
* @param gps the coordinate of the stop
* @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) {
ArrayList<Stop> stopList = tmp.get(name);
double[] coords = getCoords(gps);
Stop newStop = new Stop(lineId, name, coords[0], coords[1]);
nodes.add(newStop);
stopList = stopList == null ? new ArrayList<>() : stopList;
stopList.add(newStop);
tmp.put(name, stopList);
for (Stop s : lineChanges) {
double dist = GPS.distance(coords[0], coords[1], s.getLatitude(), s.getLongitude());
int time = (int) (dist * 1000 / WALK_SPEED);
Connection c1 = new Connection(s, "WALK", dist, time);
connections.computeIfAbsent(newStop, k -> new HashSet<>()).add(c1);
// 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) {
Connection c2 = new Connection(newStop, "WALK", dist, time);
connections.computeIfAbsent(s, k -> new HashSet<>()).add(c2);
}
return newStop;
}
double dist = GPS.distance(coords[0], coords[1], stop.getLatitude(), stop.getLongitude());
if(dist == 0) {
stop.addLine(lineId);
return stop;
}
if(dist < ERROR_MARGIN) {
lineChanges.add(stop);
}
}
}
/**
* 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);
Stop newStop = new Stop(lineId, name, coords[0], coords[1]);
nodes.add(newStop);
stopList = stopList == null ? new ArrayList<>() : stopList;
stopList.add(newStop);
tmp.put(name, stopList);
for(Stop s : lineChanges) {
double dist = GPS.distance(coords[0], coords[1], s.getLatitude(), s.getLongitude());
int time = (int) (dist*1000/WALK_SPEED);
Connection c1 = new Connection(s, "WALK", dist, time);
connections.computeIfAbsent(newStop, k -> new HashSet<>()).add(c1);
String[] timeString = line[IDFM_TRACE_TIME_INDEX].split(":");
String time0WithoutComma = timeString[0].replace(",", "");
int time = Integer.parseInt(time0WithoutComma) * 60 + Integer.parseInt(timeString[1]);
Connection c2 = new Connection(newStop, "WALK", dist, time);
connections.computeIfAbsent(s, k -> new HashSet<>()).add(c2);
}
return newStop;
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;
//If the stop has already been processed, it is not reprocessed.
if (processed.contains(current)) {
return;
}
processed.add(current);
Set<Connection> neighborhood = connections.get(current);
if (neighborhood == null) {
return;
}
/**
* 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);
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]));
connections.computeIfAbsent(fromStop, k -> new HashSet<>()).add(connection);
ArrayList<Connection> directions = new ArrayList<>();
for (Connection n : neighborhood) {
if (n.getLineName().equals(line)
&& (previous == null || !n.getStop().getName().equals(previous.getName()))
) {
directions.add(n);
}
}
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;}
processed.add(current);
Set<Connection> neighborhood = connections.get(current);
if(neighborhood == null) {return;}
ArrayList<Connection> directions = new ArrayList<>();
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;}
Stop next_stop = null;
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) {
next_stop = d.getStop();
break;
}
}
if(next_stop == null) {
return;
}
}
else {
next_stop = directions.get(0).getStop();
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) {
n.addSchedule(time);
time += n.getTime() + STOP_TIME;
addScheduleRec(next_stop, current, line, bifurcations, time, stopsHashSet, connections, processed);
return;
}
}
if (directions.size() == 0) {
return;
}
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(",");
bifurcations = new ArrayList<>();
for(String n : b){
bifurcations.add(Integer.parseInt(n.trim()));
}
Stop next_stop = null;
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) {
next_stop = d.getStop();
break;
}
String name = input[2];
String[] timeString = input[3].split(":");
int time = Integer.parseInt(timeString[0]) * 3600 + Integer.parseInt(timeString[1])*60;
ArrayList<Stop> stops = stopsHashSet.get(name);
if(stops == null) {return;}
for(Stop stop : stops) {
if(stop.getLines().contains(line)) {
addScheduleRec(stop, null, line, bifurcations, time, stopsHashSet, connections, new HashSet<>());
}
}
if (next_stop == null) {
return;
}
} else {
next_stop = directions.get(0).getStop();
if (directions.get(0).getBifurcation() != 0) {
if (bifurcations.size() > 0 && directions.get(0).getBifurcation() == bifurcations.get(0)) {
bifurcations.remove(0);
}
}
}
public void parseFiles(){
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);
return;
}
}
}
IDFMNetworkExtractor.buildFiles();
private static void addSchedule(String[] input, HashMap<String, ArrayList<Stop>> stopsHashSet,
HashMap<Stop, Set<Connection>> connections) {
try {
String line = input[0];
CSVTools.readCSVFromFile(TRACE_FILE_NAME,
(String[] line) -> addLine(line, nodes, tmp, connections));
ArrayList<Integer> bifurcations = new ArrayList<>();
if (!input[1].equals("[]")) {
String[] b = input[1].substring(1, input[1].length() - 1).split(",");
bifurcations = new ArrayList<>();
for (String n : b) {
bifurcations.add(Integer.parseInt(n.trim()));
}
}
CSVTools.readCSVFromFile(HOURS_FILE_NAME,
(String[] line) -> addSchedule(line, tmp, connections));
String name = input[2];
for(Set<Connection> set : connections.values()) {
for(Connection c : set) {
c.sortSchedule();
}
}
String[] timeString = input[3].split(":");
int time = Integer.parseInt(timeString[0]) * 3600 + Integer.parseInt(timeString[1]) * 60;
} catch (IOException e) {
LOGGER.log(Level.SEVERE, "Error while reading the line paths", e);
ArrayList<Stop> stops = stopsHashSet.get(name);
if (stops == null) {
return;
}
for (Stop stop : stops) {
if (stop.getLines().contains(line)) {
addScheduleRec(stop, null, line, bifurcations, time, stopsHashSet, connections,
new HashSet<>());
}
}
}
public void parseFiles() {
IDFMNetworkExtractor.buildFiles();
try {
CSVTools.readCSVFromFile(TRACE_FILE_NAME,
(String[] line) -> addLine(line, nodes, tmp, connections));
CSVTools.readCSVFromFile(HOURS_FILE_NAME,
(String[] line) -> addSchedule(line, tmp, connections));
for (Set<Connection> set : connections.values()) {
for (Connection c : set) {
c.sortSchedule();
}
}
} catch (IOException e) {
LOGGER.log(Level.SEVERE, "Error while reading the line paths", e);
}
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);
}
}
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,50 +1,48 @@
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 double distance;
private final double travelTime;
private final String line;
private final Connection connection;
private double distance;
private String line;
public Path(Stop current, Connection connection, double startTime) {
this.current = current;
this.connection = connection;
this.next = connection.getStop();
this.startTime = startTime;
this.travelTime = connection.getTime();
this.line = connection.getLineName();
}
private Connection connection;
public Connection getConnection() {
return this.connection;
}
public Path(Stop current, Connection connection, double startTime) {
this.current = current;
this.connection = connection;
this.next = connection.getStop();
this.startTime = startTime;
this.travelTime = connection.getTime();
this.line = connection.getLineName();
}
public Stop getCurrentStop() {
return this.current;
}
public Connection getConnection(){
return this.connection;
}
public Stop getNextStop() {
return next;
}
public Stop getCurrentStop() {
return this.current;
}
public double getStartTime() {
return this.startTime;
}
public Stop getNextStop() {
return next;
}
public double travelTime() {
return this.travelTime;
}
public double getStartTime() {
return this.startTime;
}
public double travelTime() {
return this.travelTime;
}
public String getLine() {
return this.line;
}
public String getLine() {
return this.line;
}
}

View file

@ -4,87 +4,90 @@ import java.util.HashSet;
import java.util.Set;
public class Stop implements GraphNode {
// The total number of stops
private static int counter = 0;
private final int id;
// The total number of stops
private static int counter = 0;
// The set of all the lines the stop is on
private final Set<String> lines;
private final int id;
private final String name;
// The set of all the lines the stop is on
private final Set<String> lines;
private final double latitude;
private final String name;
private final double longitude;
private final double latitude;
private double f;
private final double longitude;
public Stop(String line, String name, double latitude, double longitude) {
lines = new HashSet<>();
lines.add(line);
this.id = counter++;
this.name = name;
this.latitude = latitude;
this.longitude = longitude;
this.f = 0;
}
private double f;
@Override
public String toString() {
return "Stop{" +
"id=" + id +
", lines=" + lines +
", name='" + name + '\'' +
", latitude=" + latitude +
", longitude=" + longitude +
'}';
}
public Stop(String line, String name, double latitude, double longitude) {
lines = new HashSet<>();
lines.add(line);
this.id = counter++;
this.name = name;
this.latitude = latitude;
this.longitude = longitude;
this.f = 0;
}
@Override
public int getId(){
return id;
}
@Override
public String toString() {
return "Stop{" +
"id=" + id +
", lines=" + lines +
", name='" + name + '\'' +
", latitude=" + latitude +
", longitude=" + longitude +
'}';
}
@Override
public double getHeuristicCost(Stop goalNode) {
return 0;
}
@Override
public int getId() {
return id;
}
@Override
public Set<Stop> getNeighbors() {
return null;
}
@Override
public double getHeuristicCost(Stop goalNode) {
return 0;
}
@Override
public double getCost(Stop neighbor) {
return 0;
}
@Override
public Set<Stop> getNeighbors() {
return null;
}
@Override
public double getF() {
return f;
}
@Override
public double getCost(Stop neighbor) {
return 0;
}
public void setF(double value) {
this.f = value;
}
@Override
public double getF() {
return f;
}
public String getName(){
return name;
}
public void setF(double value) {
this.f = value;
}
public double getLatitude(){
return latitude;
}
public String getName() {
return name;
}
public double getLongitude(){
return longitude;
}
public double getLatitude() {
return latitude;
}
public void addLine(String s){
lines.add(s);
}
public double getLongitude() {
return longitude;
}
public Set<String> getLines() { return this.lines; }
public void addLine(String s) {
lines.add(s);
}
public Set<String> getLines() {
return this.lines;
}
}

View file

@ -1,54 +1,58 @@
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 */
private static final Logger LOGGER = Logger
.getLogger(IDFMNetworkExtractor.class.getName());
// OpenStreetMap API URL
private static final String OSM_URL = "https://nominatim.openstreetmap.org/search";
/**
* The logger for information on the process
*/
private static final Logger LOGGER = Logger
.getLogger(IDFMNetworkExtractor.class.getName());
public static double[] getGPSLocation(String term) {
try {
String urlString = String.format("%s?q=%s&format=json", OSM_URL, URLEncoder.encode(term, StandardCharsets.UTF_8));
HttpURLConnection connection = (HttpURLConnection) new URL(urlString).openConnection();
// OpenStreetMap API URL
private static final String OSM_URL = "https://nominatim.openstreetmap.org/search";
connection.setRequestMethod("GET");
public static double[] getGPSLocation(String term) {
try {
String urlString = String.format("%s?q=%s&format=json", OSM_URL,
URLEncoder.encode(term, StandardCharsets.UTF_8));
HttpURLConnection connection = (HttpURLConnection) new URL(urlString).openConnection();
BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String inputLine;
StringBuilder response = new StringBuilder();
connection.setRequestMethod("GET");
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String inputLine;
StringBuilder response = new StringBuilder();
JSONArray jsonArray = new JSONArray(response.toString());
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
if (!jsonArray.isEmpty()) {
JSONObject firstResult = jsonArray.getJSONObject(0);
JSONArray jsonArray = new JSONArray(response.toString());
double lat = firstResult.getDouble("lat");
double lon = firstResult.getDouble("lon");
return new double[]{lat, lon};
}
}
catch (IOException e) {
LOGGER.log(Level.SEVERE, e,
() -> "Error accessing the API");
}
return new double[]{0, 0};
if (!jsonArray.isEmpty()) {
JSONObject firstResult = jsonArray.getJSONObject(0);
double lat = firstResult.getDouble("lat");
double lon = firstResult.getDouble("lon");
return new double[]{lat, lon};
}
} catch (IOException e) {
LOGGER.log(Level.SEVERE, e,
() -> "Error accessing the API");
}
return new double[]{0, 0};
}
}

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,91 +10,115 @@ 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 */
private CSVTools() {
// 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
* @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
*/
private static void readCSVFromInputStream(InputStream is, Consumer<String[]> contentLineConsumer)
throws IOException {
ICSVParser parser = new CSVParserBuilder().withSeparator(';').build();
try (Reader reader = new BufferedReader(
new InputStreamReader(is, StandardCharsets.UTF_8))) {
CSVReaderBuilder csvBuilder = new CSVReaderBuilder(reader)
.withCSVParser(parser);
try (CSVReader csv = csvBuilder.build()) {
String[] line = csv.readNextSilently(); // Eliminate header
while (csv.peek() != null) {
line = csv.readNext();
contentLineConsumer.accept(line);
}
}
} catch (CsvValidationException e) {
throw new IOException("Invalid csv file", e); //$NON-NLS-1$
/**
* 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
*/
private static void readCSVFromInputStream(InputStream is, Consumer<String[]> contentLineConsumer)
throws IOException {
ICSVParser parser = new CSVParserBuilder().withSeparator(';').build();
try (Reader reader = new BufferedReader(
new InputStreamReader(is, StandardCharsets.UTF_8))) {
CSVReaderBuilder csvBuilder = new CSVReaderBuilder(reader)
.withCSVParser(parser);
try (CSVReader csv = csvBuilder.build()) {
String[] line = csv.readNextSilently(); // Eliminate header
while (csv.peek() != null) {
line = csv.readNext();
contentLineConsumer.accept(line);
}
}
} catch (CsvValidationException e) {
throw new IOException("Invalid csv file", e); //$NON-NLS-1$
}
}
/** 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
*/
public static void readCSVFromFile(String filename, Consumer<String[]> contentLineConsumer)
throws IOException {
File file = new File(filename);
readCSVFromInputStream(new FileInputStream(file), contentLineConsumer);
/**
* 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
*/
public static void readCSVFromFile(String filename, Consumer<String[]> contentLineConsumer)
throws IOException {
File file = new File(filename);
readCSVFromInputStream(new FileInputStream(file), contentLineConsumer);
}
/**
* 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
*/
public static void readCSVFromURL(String url, Consumer<String[]> contentLineConsumer)
throws IOException {
readCSVFromInputStream(new URL(url).openStream(), contentLineConsumer);
}
/**
* 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(csv::writeNext);
}
}
}
/** 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
*/
public static void readCSVFromURL(String url, Consumer<String[]> contentLineConsumer)
throws IOException {
readCSVFromInputStream(new URL(url).openStream(), contentLineConsumer);
}
/** 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(csv::writeNext);
}
}
}
// /** 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));
// }
// }
// }
// /** 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));
// }
// }
// }
}

View file

@ -1,47 +1,47 @@
/**
*
*
*/
package fr.u_paris.gla.project.utils;
/** A utility class for computations related to GPS.
*
*
* @author Emmanuel Bigeon */
public final class GPS {
/** The value of a flat angle, in degrees. */
private static final int FLAT_ANGLE_DEGREE = 180;
/** The (approximated) earth radius in km. */
private static final double EARTH_RADIUS = 6_370.0;
/** The value of a flat angle, in degrees. */
private static final int FLAT_ANGLE_DEGREE = 180;
/** The (approximated) earth radius in km. */
private static final double EARTH_RADIUS = 6_370.0;
/** Hidden constructor for tool class */
private GPS() {
// Tool class
}
/** Hidden constructor for tool class */
private GPS() {
// Tool class
}
/** Convert a degree angle value in a radian angle one.
*
* @param degree the degree value
* @return the radian value */
private static double degreeToRadian(double degree) {
return degree / FLAT_ANGLE_DEGREE * Math.PI;
}
/** Convert a degree angle value in a radian angle one.
*
* @param degree the degree value
* @return the radian value */
private static double degreeToRadian(double degree) {
return degree / FLAT_ANGLE_DEGREE * Math.PI;
}
/** Compute the flying distance between two GPS positions.
*
* @param latitude1 the latitude of the first position
* @param longitude1 the longitude of the first position
* @param latitude2 the latitude of the second position
* @param longitude2 the longitude of the second position
* @return the flying distance in km*/
public static double distance(double latitude1, double longitude1, double latitude2,
double longitude2) {
latitude1 = degreeToRadian(latitude1);
latitude2 = degreeToRadian(latitude2);
double deltaLatitude = latitude2 - latitude1;
double deltaLongitude = degreeToRadian(longitude2 - longitude1);
double a = Math.pow(Math.sin(deltaLatitude / 2), 2)
+ Math.pow(Math.sin(deltaLongitude / 2), 2) * Math.cos(latitude1)
* Math.cos(latitude2);
return 2 * EARTH_RADIUS * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
}
/** Compute the flying distance between two GPS positions.
*
* @param latitude1 the latitude of the first position
* @param longitude1 the longitude of the first position
* @param latitude2 the latitude of the second position
* @param longitude2 the longitude of the second position
* @return the flying distance in km*/
public static double distance(double latitude1, double longitude1, double latitude2,
double longitude2) {
latitude1 = degreeToRadian(latitude1);
latitude2 = degreeToRadian(latitude2);
double deltaLatitude = latitude2 - latitude1;
double deltaLongitude = degreeToRadian(longitude2 - longitude1);
double a = Math.pow(Math.sin(deltaLatitude / 2), 2)
+ Math.pow(Math.sin(deltaLongitude / 2), 2) * Math.cos(latitude1)
* Math.cos(latitude2);
return 2 * EARTH_RADIUS * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
}
}

View file

@ -4,11 +4,16 @@ 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 :-) */
@Test
public void testPlaceholder() {
assertTrue(true, "It should be true that true is true...");
}
/**
* 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,111 +15,119 @@ 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 {
//Test de hasNext, pour le cas ou il y'a un trace et cas ou il n'y en a pas
@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");
//Test de hasNext, pour le cas ou il y'a un trace et cas ou il n'y en a pas
@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");
// 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);
// 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");
trace.addPath(path);
TraceEntry trace = new TraceEntry("Ligne1", "IDFM:03434", "Bus", "dummy_url");
trace.addPath(path);
CSVStreamProvider providerWithTrace = new CSVStreamProvider(Arrays.asList(trace).iterator(),null);
assertTrue(providerWithTrace.hasNext(), "hasNext should return true when traces are provided");
}
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() {
// Initialisation des données d'exemple directement dans le test
StopEntry start = new StopEntry("Début", 2.3522, 48.8566); // Paris
StopEntry end = new StopEntry("Fin", 2.295, 48.8738); // Proche de Paris
//Test de la methode next()
@Test
public void testNext() {
// Initialisation des données d'exemple directement dans le test
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.addPath(Arrays.asList(start, end)); // Ajout d'un chemin à la trace
CSVStreamProvider provider = new CSVStreamProvider(Collections.singletonList(traceEntry).iterator(),null);
TraceEntry traceEntry = new TraceEntry("Ligne1", "IDFM:03434", "Bus", "dummy_url");
traceEntry.addPath(Arrays.asList(start, end)); // Ajout d'un chemin à la trace
assertTrue(provider.hasNext(), "Doit avoir un prochain élément");
CSVStreamProvider provider = new CSVStreamProvider(
Collections.singletonList(traceEntry).iterator(), null);
String[] result = provider.next();
assertNotNull(result, "Le résultat ne doit pas être null");
assertTrue(provider.hasNext(), "Doit avoir un prochain élément");
// 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");
String[] result = provider.next();
assertNotNull(result, "Le résultat ne doit pas être null");
// 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");
}
// 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");
// 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");
}
//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
String[] nextLine = new String[NetworkFormat.NUMBER_COLUMNS];
//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
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);
fillStationMethod.setAccessible(true);
// Accès à la méthode fillStation via la réflexion
Method fillStationMethod = CSVStreamProvider.class.getDeclaredMethod("fillStation", StopEntry.class, String[].class, int.class);
fillStationMethod.setAccessible(true);
// Invocation de la méthode fillStation
fillStationMethod.invoke(null, stop, nextLine, NetworkFormat.START_INDEX);
// Invocation de la méthode fillStation
fillStationMethod.invoke(null, stop, nextLine, NetworkFormat.START_INDEX);
// Format attendu pour la latitude et la longitude
NumberFormat gpsFormatter = NetworkFormat.getGPSFormatter();
String expectedLatitudeLongitude = MessageFormat.format("{0}, {1}",
gpsFormatter.format(stop.latitude),
gpsFormatter.format(stop.longitude));
// Format attendu pour la latitude et la longitude
NumberFormat gpsFormatter = NetworkFormat.getGPSFormatter();
String expectedLatitudeLongitude = MessageFormat.format("{0}, {1}",
gpsFormatter.format(stop.latitude),
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.");
}
// 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.");
}
//Test de la méthode static private distanceToTime()
@Test
public void testDistanceToTime() throws Exception {
// Valeurs fictives pour TWO_ACCELERATION_DISTANCE et MAX_SPEED
final double TWO_ACCELERATION_DISTANCE = 0.2; // Par exemple
final double MAX_SPEED = 5.0; // Par exemple
// Exemple de distance à tester
double distanceExample = 1.0; // 1 km
//Test de la méthode static private distanceToTime()
@Test
public void testDistanceToTime() throws Exception {
// Valeurs fictives pour TWO_ACCELERATION_DISTANCE et MAX_SPEED
final double TWO_ACCELERATION_DISTANCE = 0.2; // Par exemple
final double MAX_SPEED = 5.0; // Par exemple
// 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);
// Accès à la méthode distanceToTime via la réflexion
Method method = CSVStreamProvider.class.getDeclaredMethod("distanceToTime", double.class);
method.setAccessible(true);
// Invocation de la méthode distanceToTime et stockage du résultat
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.");
}
// 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);
// Accès à la méthode distanceToTime via la réflexion
Method method = CSVStreamProvider.class.getDeclaredMethod("distanceToTime", double.class);
method.setAccessible(true);
// Invocation de la méthode distanceToTime et stockage du résultat
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.");
}
}

View file

@ -1,59 +1,67 @@
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 {
//Test de clenLine de ma classe IDFMNetworkExtractor
@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
// 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
// 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)));
// Accès à la méthode cleanLine via la réflexion
Method cleanLineMethod = IDFMNetworkExtractor.class.getDeclaredMethod("cleanLine", List.class);
cleanLineMethod.setAccessible(true);
// Invocation de la méthode cleanLine
boolean result = (Boolean) cleanLineMethod.invoke(null, paths);
// 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.");
}
//Test de clenLine de ma classe IDFMNetworkExtractor
@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
// 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
// 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<>(List.of(List.of(unidentifiedStop)));
// Accès à la méthode cleanLine via la réflexion
Method cleanLineMethod = IDFMNetworkExtractor.class.getDeclaredMethod("cleanLine", List.class);
cleanLineMethod.setAccessible(true);
// Invocation de la méthode cleanLine
boolean result = (Boolean) cleanLineMethod.invoke(null, paths);
// 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.");
}
@Test
public void testAddCandidate() throws Exception {
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);
@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");
trace.addPath(path);
StopEntry candidate = new StopEntry("Proche Candidat", 2.3523, 48.8567); // Coordonnées proches
StopEntry candidate = new StopEntry("Proche Candidat", 2.3523, 48.8567); // Coordonnées proches
Method method = IDFMNetworkExtractor.class.getDeclaredMethod("addCandidate", TraceEntry.class,
StopEntry.class);
method.setAccessible(true);
Method method = IDFMNetworkExtractor.class.getDeclaredMethod("addCandidate", TraceEntry.class, StopEntry.class);
method.setAccessible(true);
method.invoke(null, trace, candidate);
method.invoke(null, trace, candidate);
//L'appel c'est derouler correctement
assertTrue(true, "L'appel de addCandidate s'est déroulé sans erreur.");
}
//L'appel c'est derouler correctement
assertTrue(true, "L'appel de addCandidate s'est déroulé sans erreur.");
}
}

View file

@ -1,10 +1,14 @@
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 {
//Test de toString
//Test de toString
/*
@Test
public void testToString() {
@ -15,49 +19,49 @@ public class StopEntryTest {
}
*/
//Si le 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);
// Mise à jour de la valeur attendue pour correspondre au formatage réel
String expected = "Chatelet [2.346, 48.853]";
assertEquals(expected, stop.toString());
}
//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);
// Mise à jour de la valeur attendue pour correspondre au formatage réel
String expected = "Chatelet [2.346, 48.853]";
assertEquals(expected, stop.toString());
}
//Test de compareTo
@Test
public void testCompareTo() {
StopEntry stop1 = new StopEntry("Chatelet", 2.3467, 48.8534);
StopEntry stop2 = new StopEntry("Louvre", 2.3360, 48.8606);
assertTrue(stop1.compareTo(stop2) < 0); //
assertTrue(stop2.compareTo(stop1) > 0); //
// 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
StopEntry stop4 = new StopEntry("Chatelet", 2.3500, 48.8500);
assertTrue(stop1.compareTo(stop4) > 0);
}
//Test de hashCode
@Test
public void testHashCode() {
StopEntry stop1 = new StopEntry("Chatelet", 2.3467, 48.8534);
StopEntry stop2 = new StopEntry("Chatelet", 2.3467, 48.8534);
assertEquals(stop1.hashCode(), stop2.hashCode());
}
//Test de compareTo
@Test
public void testCompareTo() {
StopEntry stop1 = new StopEntry("Chatelet", 2.3467, 48.8534);
StopEntry stop2 = new StopEntry("Louvre", 2.3360, 48.8606);
assertTrue(stop1.compareTo(stop2) < 0); //
assertTrue(stop2.compareTo(stop1) > 0); //
//Test de equals
@Test
public void testEquals() {
StopEntry stop1 = new StopEntry("Chatelet", 2.3467, 48.8534);
StopEntry stop2 = new StopEntry("Chatelet", 2.3467, 48.8534);
StopEntry stop3 = new StopEntry("Louvre", 2.3360, 48.8606);
assertEquals(stop1, stop2);
assertNotEquals(stop1, stop3);
}
// 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
StopEntry stop4 = new StopEntry("Chatelet", 2.3500, 48.8500);
assertTrue(stop1.compareTo(stop4) > 0);
}
//Test de hashCode
@Test
public void testHashCode() {
StopEntry stop1 = new StopEntry("Chatelet", 2.3467, 48.8534);
StopEntry stop2 = new StopEntry("Chatelet", 2.3467, 48.8534);
assertEquals(stop1.hashCode(), stop2.hashCode());
}
//Test de equals
@Test
public void testEquals() {
StopEntry stop1 = new StopEntry("Chatelet", 2.3467, 48.8534);
StopEntry stop2 = new StopEntry("Chatelet", 2.3467, 48.8534);
StopEntry stop3 = new StopEntry("Louvre", 2.3360, 48.8606);
assertEquals(stop1, stop2);
assertNotEquals(stop1, stop3);
}
}

View file

@ -1,68 +1,72 @@
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 {
@Test
public void testIsStopConnected() {
@Test
public void testIsStopConnected() {
Stop stop = new Stop("Stop1");
BifStop bifStop1 = new BifStop(1, new Stop("Stop2"));
// Initially, no stops are connected
assertFalse(stop.isStopConnected("Stop2"));
Stop stop = new Stop("Stop1");
BifStop bifStop1 = new BifStop(1, new Stop("Stop2"));
// Initially, no stops are connected
assertFalse(stop.isStopConnected("Stop2"));
// Add a connected stop
stop.addConnectedStop(bifStop1);
// Add a connected stop
stop.addConnectedStop(bifStop1);
// Now, Stop2 should be connected
assertTrue(stop.isStopConnected("Stop2"));
}
// Now, Stop2 should be connected
assertTrue(stop.isStopConnected("Stop2"));
}
@Test
public void testGetConnectedStop() {
@Test
public void testGetConnectedStop() {
Stop stop = new Stop("Stop1");
BifStop bifStop1 = new BifStop(1, new Stop("Stop2"));
BifStop bifStop2 = new BifStop(2, new Stop("Stop3"));
Stop stop = new Stop("Stop1");
BifStop bifStop1 = new BifStop(1, new Stop("Stop2"));
BifStop bifStop2 = new BifStop(2, new Stop("Stop3"));
// Add two connected stops
stop.addConnectedStop(bifStop1);
stop.addConnectedStop(bifStop2);
// Add two connected stops
stop.addConnectedStop(bifStop1);
stop.addConnectedStop(bifStop2);
// Retrieve the connected stops
BifStop retrievedStop1 = stop.getConnectedStop("Stop2");
BifStop retrievedStop2 = stop.getConnectedStop("Stop3");
// Retrieve the connected stops
BifStop retrievedStop1 = stop.getConnectedStop("Stop2");
BifStop retrievedStop2 = stop.getConnectedStop("Stop3");
// Check if the correct stops were retrieved
assertEquals(bifStop1, retrievedStop1);
assertEquals(bifStop2, retrievedStop2);
}
// Check if the correct stops were retrieved
assertEquals(bifStop1, retrievedStop1);
assertEquals(bifStop2, retrievedStop2);
}
@Test
public void testAddConnectedStop() {
Stop stop = new Stop("Stop1");
BifStop bifStop1 = new BifStop(1, new Stop("Stop2"));
@Test
public void testAddConnectedStop() {
Stop stop = new Stop("Stop1");
BifStop bifStop1 = new BifStop(1, new Stop("Stop2"));
// Add a connected stop
stop.addConnectedStop(bifStop1);
// Add a connected stop
stop.addConnectedStop(bifStop1);
// Check if the stop was added
assertTrue(stop.isStopConnected("Stop2"));
}
// Check if the stop was added
assertTrue(stop.isStopConnected("Stop2"));
}
@Test
public void testSHJH(){
Stop stop = new Stop("Stop2323");
BifStop bifStop1 = new BifStop(1, new Stop("Stop2323"));
@Test
public void testSHJH() {
Stop stop = new Stop("Stop2323");
BifStop bifStop1 = new BifStop(1, new Stop("Stop2323"));
// Add a connected stop
stop.addConnectedStop(bifStop1);
// Add a connected stop
stop.addConnectedStop(bifStop1);
// Check if the stop was added
assertTrue(stop.isStopConnected("Stop2323"));
}
// Check if the stop was added
assertTrue(stop.isStopConnected("Stop2323"));
}
}

View file

@ -1,48 +1,54 @@
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");
String terminus1 = "Terminus A";
String terminus2 = "Terminus B";
//Ajouter des arrêt sur la ligne
traceEntry.addTerminus(terminus1);
traceEntry.addTerminus(terminus2);
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.");
}
//addTerminus
@Test
public void testAddTerminus() {
TraceEntry traceEntry = new TraceEntry("Ligne 1", "IDFM:03434", "Bus", "dummy_url");
String terminus1 = "Terminus A";
String terminus2 = "Terminus B";
//addPath
@Test
public void testAddPath() {
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);
traceEntry.addPath(path);
List<List<StopEntry>> paths = traceEntry.getPaths();
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.");
}
//Ajouter des arrêt sur la ligne
traceEntry.addTerminus(terminus1);
traceEntry.addTerminus(terminus2);
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.");
}
//addPath
@Test
public void testAddPath() {
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);
traceEntry.addPath(path);
List<List<StopEntry>> paths = traceEntry.getPaths();
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.");
}
//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");
assertEquals("Ligne 1", traceEntry.lname, "Le nom de la ligne doit être 'Ligne 1'.");
}
//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");
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 {
@ -33,32 +31,32 @@ public class TransportTest {
assertEquals(List.of(1, 2, 3), result.getValue());
}*/
@Test
public void testIsTerminus() {
Transport transport = new Transport("Test Line", "Bus", "dummy_url");
transport.addStop("A", "B", 1);
transport.addStop("B", "C", 2);
transport.addStop("C", "D", 3);
TraceDescription td = new TraceDescription("A", "D", "A", "D");
transport.descriptions.add(td);
@Test
public void testIsTerminus() {
Transport transport = new Transport("Test Line", "Bus", "dummy_url");
transport.addStop("A", "B", 1);
transport.addStop("B", "C", 2);
transport.addStop("C", "D", 3);
TraceDescription td = new TraceDescription("A", "D", "A", "D");
transport.descriptions.add(td);
assertTrue(transport.isTerminus("A"));
assertTrue(transport.isTerminus("D"));
assertFalse(transport.isTerminus("B"));
}
assertTrue(transport.isTerminus("A"));
assertTrue(transport.isTerminus("D"));
assertFalse(transport.isTerminus("B"));
}
@Test
public void testAddStop() {
Transport transport = new Transport("Test Line", "Bus", "dummy_url");
transport.addStop("A", "B", 1);
transport.addStop("B", "C", 2);
transport.addStop("C", "D", 3);
TraceDescription td = new TraceDescription("A", "D", "A", "D");
transport.descriptions.add(td);
@Test
public void testAddStop() {
Transport transport = new Transport("Test Line", "Bus", "dummy_url");
transport.addStop("A", "B", 1);
transport.addStop("B", "C", 2);
transport.addStop("C", "D", 3);
TraceDescription td = new TraceDescription("A", "D", "A", "D");
transport.descriptions.add(td);
transport.addStop("D", "E", 4);
assertTrue(transport.stopsMap.containsKey("E"));
assertEquals("E", transport.stopsMap.get("E").name);
assertTrue(transport.stopsMap.get("D").isStopConnected("E"));
}
transport.addStop("D", "E", 4);
assertTrue(transport.stopsMap.containsKey("E"));
assertEquals("E", transport.stopsMap.get("E").name);
assertTrue(transport.stopsMap.get("D").isStopConnected("E"));
}
}

View file

@ -1,84 +1,85 @@
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;
public class UnidentifiedStopEntryTest {
// Test de la méthode resolve de la classe UnidentifiedStopEntry
@Test
public void testResolve() {
// Création d'un UnidentifiedStopEntry avec des coordonnées arbitraires (0,0)
UnidentifiedStopEntry unidentifiedStopEntry = new UnidentifiedStopEntry(0, 0);
// Test de la méthode resolve de la classe UnidentifiedStopEntry
@Test
public void testResolve() {
// Création d'un UnidentifiedStopEntry avec des coordonnées arbitraires (0,0)
UnidentifiedStopEntry unidentifiedStopEntry = new UnidentifiedStopEntry(0, 0);
// Test lorsque la liste des candidats est vide
assertNull(unidentifiedStopEntry.resolve());
// Test lorsque la liste des candidats est vide
assertNull(unidentifiedStopEntry.resolve());
// Test lorsque la liste des candidats contient un seul StopEntry
StopEntry stopEntry1 = new StopEntry("Stop1", 10.0, 20.0);
unidentifiedStopEntry.addCandidate(stopEntry1);
assertEquals(stopEntry1, unidentifiedStopEntry.resolve());
// Test lorsque la liste des candidats contient un seul StopEntry
StopEntry stopEntry1 = new StopEntry("Stop1", 10.0, 20.0);
unidentifiedStopEntry.addCandidate(stopEntry1);
assertEquals(stopEntry1, unidentifiedStopEntry.resolve());
// Test lorsque la liste des candidats contient plusieurs StopEntries
StopEntry stopEntry2 = new StopEntry("Stop2", 30.0, 40.0);
unidentifiedStopEntry.addCandidate(stopEntry2);
// En supposant que la méthode GPS.distance fonctionne correctement, stopEntry1 devrait être plus proche
assertEquals(stopEntry1, unidentifiedStopEntry.resolve());
// Test lorsque la liste des candidats contient plusieurs StopEntries
StopEntry stopEntry2 = new StopEntry("Stop2", 30.0, 40.0);
unidentifiedStopEntry.addCandidate(stopEntry2);
// En supposant que la méthode GPS.distance fonctionne correctement, stopEntry1 devrait être plus proche
assertEquals(stopEntry1, unidentifiedStopEntry.resolve());
// Test lorsque la liste des candidats contient plusieurs StopEntries et que le plus proche change
UnidentifiedStopEntry unidentifiedStopEntry2 = new UnidentifiedStopEntry(35.0, 45.0);
unidentifiedStopEntry2.addCandidate(stopEntry1);
unidentifiedStopEntry2.addCandidate(stopEntry2);
// Maintenant, stopEntry1 devrait être plus proche
assertEquals(stopEntry2, unidentifiedStopEntry2.resolve());
}
// Test lorsque la liste des candidats contient plusieurs StopEntries et que le plus proche change
UnidentifiedStopEntry unidentifiedStopEntry2 = new UnidentifiedStopEntry(35.0, 45.0);
unidentifiedStopEntry2.addCandidate(stopEntry1);
unidentifiedStopEntry2.addCandidate(stopEntry2);
// Maintenant, stopEntry1 devrait être plus proche
assertEquals(stopEntry2, unidentifiedStopEntry2.resolve());
}
// Test de la méthode addCandidate de la classe UnidentifiedStopEntry
@Test
public void testAddCandidate() {
// Création d'un UnidentifiedStopEntry avec des coordonnées arbitraires (0,0)
UnidentifiedStopEntry unidentifiedStopEntry = new UnidentifiedStopEntry(0, 0);
// Test de la méthode addCandidate de la classe UnidentifiedStopEntry
@Test
public void testAddCandidate() {
// Création d'un UnidentifiedStopEntry avec des coordonnées arbitraires (0,0)
UnidentifiedStopEntry unidentifiedStopEntry = new UnidentifiedStopEntry(0, 0);
// Test lorsque nous ajoutons un StopEntry à la liste des candidats
StopEntry stopEntry1 = new StopEntry("Stop1", 10.0, 20.0);
unidentifiedStopEntry.addCandidate(stopEntry1);
assertEquals(stopEntry1, unidentifiedStopEntry.resolve());
// Test lorsque nous ajoutons un StopEntry à la liste des candidats
StopEntry stopEntry1 = new StopEntry("Stop1", 10.0, 20.0);
unidentifiedStopEntry.addCandidate(stopEntry1);
assertEquals(stopEntry1, unidentifiedStopEntry.resolve());
// Test lorsque nous ajoutons un autre StopEntry à la liste des candidats
StopEntry stopEntry2 = new StopEntry("Stop2", 30.0, 40.0);
unidentifiedStopEntry.addCandidate(stopEntry2);
// En supposant que la méthode GPS.distance fonctionne correctement, stopEntry1 devrait être plus proche
assertEquals(stopEntry1, unidentifiedStopEntry.resolve());
}
// Test lorsque nous ajoutons un autre StopEntry à la liste des candidats
StopEntry stopEntry2 = new StopEntry("Stop2", 30.0, 40.0);
unidentifiedStopEntry.addCandidate(stopEntry2);
// En supposant que la méthode GPS.distance fonctionne correctement, stopEntry1 devrait être plus proche
assertEquals(stopEntry1, unidentifiedStopEntry.resolve());
}
// Test de la méthode equals de la classe UnidentifiedStopEntry
@Test
public void testEquals() {
// Création de deux UnidentifiedStopEntry avec les mêmes coordonnées
UnidentifiedStopEntry unidentifiedStopEntry1 = new UnidentifiedStopEntry(0, 0);
UnidentifiedStopEntry unidentifiedStopEntry2 = new UnidentifiedStopEntry(0, 0);
// Test de la méthode equals de la classe UnidentifiedStopEntry
@Test
public void testEquals() {
// Création de deux UnidentifiedStopEntry avec les mêmes coordonnées
UnidentifiedStopEntry unidentifiedStopEntry1 = new UnidentifiedStopEntry(0, 0);
UnidentifiedStopEntry unidentifiedStopEntry2 = new UnidentifiedStopEntry(0, 0);
// Test lorsque nous comparons un UnidentifiedStopEntry avec lui-même
assertTrue(unidentifiedStopEntry1.equals(unidentifiedStopEntry1));
// Test lorsque nous comparons un UnidentifiedStopEntry avec lui-même
assertEquals(unidentifiedStopEntry1, unidentifiedStopEntry1);
// Test lorsque nous comparons deux UnidentifiedStopEntry qui n'ont pas de candidats
assertTrue(unidentifiedStopEntry1.equals(unidentifiedStopEntry2));
// Test lorsque nous comparons deux UnidentifiedStopEntry qui n'ont pas de candidats
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));
// 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);
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));
}
// Test lorsque nous ajoutons un autre StopEntry à l'un des UnidentifiedStopEntry
StopEntry stopEntry2 = new StopEntry("Stop2", 30.0, 40.0);
unidentifiedStopEntry1.addCandidate(stopEntry2);
assertNotEquals(unidentifiedStopEntry1, unidentifiedStopEntry2);
}
}

View file

@ -1,80 +1,77 @@
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 {
String t = "00:00";
NumberFormat GPS_test = NetworkFormat.getGPSFormatter();
@Test
public void testParseDurationEqual() {
assertEquals(Duration.ZERO, NetworkFormat.parseDuration(t));
}
@Test
public void testParseDurationTooBig() {
String y = "119:00";
assertThrows(DateTimeParseException.class, () -> NetworkFormat.parseDuration(y));
}
@Test
public void formatDuration() {
assertEquals(t, NetworkFormat.formatDuration(Duration.ZERO));
}
@Test
public void parseThenFormatDuration() {
String t = "00:00";
NumberFormat GPS_test = NetworkFormat.getGPSFormatter();
assertEquals(t, NetworkFormat.formatDuration(NetworkFormat.parseDuration(t)));
}
@Test
public void testParseDurationEqual() {
assertEquals(Duration.ZERO, NetworkFormat.parseDuration(t));
}
@Test
public void testParseDurationTooBig() {
String y = "119:00";
assertThrows(DateTimeParseException.class, () -> NetworkFormat.parseDuration(y));
}
@Test
public void formatDuration() {
assertEquals(t, NetworkFormat.formatDuration(Duration.ZERO));
}
@Test
public void parseThenFormatDuration(){
String t = "00:00";
assertEquals(t, NetworkFormat.formatDuration(NetworkFormat.parseDuration(t)));
}
@Test
public void getGPSFormatterPos() {
double GPS_pos = 1.456489615649813;
assertEquals(String.valueOf(GPS_pos), GPS_test.format(GPS_pos));
@Test
public void getGPSFormatterPos() {
double GPS_pos = 1.456489615649813;
assertEquals(String.valueOf(GPS_pos), GPS_test.format(GPS_pos));
}
}
@Test
public void getGPSFormatterNeg() {
double GPS_neg = -1.456489615649813;
assertEquals(String.valueOf(GPS_neg), GPS_test.format(GPS_neg));
@Test
public void getGPSFormatterNeg() {
double GPS_neg = -1.456489615649813;
assertEquals(String.valueOf(GPS_neg), GPS_test.format(GPS_neg));
}
@Test
public void getGPSFormatterNul() {
int GPS_nul = 0;
assertEquals(String.valueOf(GPS_nul), GPS_test.format(GPS_nul));
}
@Test
public void getGPSFormatterNul() {
int GPS_nul = 0;
assertEquals(String.valueOf(GPS_nul), GPS_test.format(GPS_nul));
}
}
@Test
public void getGPSFormatterBig() {
String string_int = "4565156498156489";
String string_float = "5675747274674276474267479751262167";
BigDecimal GPS_big = new BigDecimal(string_int + "." + string_float);
@Test
public void getGPSFormatterBig() {
String string_int = "4565156498156489";
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(" ", ""));
assertEquals(string_int + "." + string_float.substring(0, NetworkFormat.GPS_PRECISION),
GPS_test.format(GPS_big).replace(",", "").replace(" ",""));
}
}
}

View file

@ -1,33 +1,31 @@
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 {
@Test
public void getTripSequence() {
String rpz = "4,5,19,21";
List<Integer> test = Arrays.asList(4, 5, 19, 21);
@Test
public void getTripSequence() {
String rpz = "4,5,19,21";
List<Integer> test = Arrays.asList(4, 5, 19, 21);
assertEquals(test, ScheduleFormat.getTripSequence(rpz));
}
assertEquals(test, ScheduleFormat.getTripSequence(rpz));
}
@Test
public void getTimeFormatter() {
DateTimeFormatter formatter = ScheduleFormat.getTimeFormatter();
LocalDateTime date = LocalDateTime.now();
String test = date.format(formatter);
//format date: YYYY-MM-DDTHH:MM:SS.DECIMAL
assertEquals(date.toString().substring(11, 16), test);
@Test
public void getTimeFormatter() {
DateTimeFormatter formatter = ScheduleFormat.getTimeFormatter();
LocalDateTime date = LocalDateTime.now();
String test = date.format(formatter);
//format date: YYYY-MM-DDTHH:MM:SS.DECIMAL
assertEquals(date.toString().substring(11, 16), test);
}
}
}

View file

@ -1,88 +1,80 @@
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,() -> {
Consumer<String[]> test = s -> System.out.println(Arrays.toString(s));
CSVTools.readCSVFromURL("https://google.fr",
test);
}
); */
}
@Test
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);
}
);
}
@Test
public void readCSVFromURL_invalid() {
// TODO Fix the exception thrown
/**
assertThrows(IOException.class,() -> {
Consumer<String[]> test = s -> System.out.println(Arrays.toString(s));
CSVTools.readCSVFromURL("https://google.fr",
test);
String randomUniqueFilename() {
String prefix = "file_";
String randomString = UUID.randomUUID().toString().substring(0, 8);
return prefix + randomString + ".csv";
}
}
);
*/
}
@Test
void writeCSVToFile() {
String fileName = randomUniqueFilename();
assertDoesNotThrow(() -> {
String[] stuff = {"jsqdsqdsqsqffdfgzava", "pfezegrrbeebn", "dfbsduifzegbczi", "sdfsdfcy"};
String[][] t = {stuff, stuff};
Stream<String[]> test = Arrays.stream(t);
CSVTools.writeCSVToFile(fileName, test);
File tmp = new File(fileName);
tmp.delete();
});
}
@Test
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);
@Test
void writeCSVToFile_specialName() {
String fileName = randomUniqueFilename();
assertDoesNotThrow(() -> {
String[] stuff = {"jsqdsqdsqsqffdfgzava", "pfezegrrbeebn", "dfbsduifzegbczi", "sdfsdfcy"};
String[][] t = {stuff, stuff};
Stream<String[]> test = Arrays.stream(t);
CSVTools.writeCSVToFile(fileName, test);
File tmp = new File(fileName);
tmp.delete();
});
}
}
);
}
String randomUniqueFilename() {
String prefix = "file_";
String randomString = UUID.randomUUID().toString().substring(0, 8);
return prefix + randomString + ".csv";
}
@Test
void writeCSVToFile() {
String fileName = randomUniqueFilename();
assertDoesNotThrow(() -> {
String[] stuff = {"jsqdsqdsqsqffdfgzava", "pfezegrrbeebn", "dfbsduifzegbczi", "sdfsdfcy"};
String[][] t = {stuff, stuff};
Stream<String[]> test = Arrays.stream(t);
CSVTools.writeCSVToFile(fileName, test);
File tmp = new File(fileName);
tmp.delete();
});
}
@Test
void writeCSVToFile_specialName() {
String fileName = randomUniqueFilename();
assertDoesNotThrow(() -> {
String[] stuff = {"jsqdsqdsqsqffdfgzava", "pfezegrrbeebn", "dfbsduifzegbczi", "sdfsdfcy"};
String[][] t = {stuff, stuff};
Stream<String[]> test = Arrays.stream(t);
CSVTools.writeCSVToFile(fileName, test);
File tmp = new File(fileName);
tmp.delete();
});
}
@Test
void writeCSVToFile_invalidName() {
assertThrows( IOException.class ,() -> {
String[] stuff = {"jsqdsqdsqsqffdfgzava", "pfezegrrbeebn", "dfbsduifzegbczi", "sdfsdfcy"};
String[][] t = {stuff, stuff};
Stream<String[]> test = Arrays.stream(t);
CSVTools.writeCSVToFile(".", test);
});
}
@Test
void writeCSVToFile_invalidName() {
assertThrows(IOException.class, () -> {
String[] stuff = {"jsqdsqdsqsqffdfgzava", "pfezegrrbeebn", "dfbsduifzegbczi", "sdfsdfcy"};
String[][] t = {stuff, stuff};
Stream<String[]> test = Arrays.stream(t);
CSVTools.writeCSVToFile(".", test);
});
}
}

View file

@ -1,39 +1,41 @@
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(){
assertDoesNotThrow(
() -> {
GPS.distance(5, 3, 5, 11);
}
);
}
@Test
public void testDistance_SameLat() {
assertDoesNotThrow(
() -> {
GPS.distance(5, 3, 5, 11);
}
);
}
@Test
public void distance_SameLon(){
assertDoesNotThrow(
() -> {
GPS.distance(5, 3, 7, 3);
}
);
}
@Test
public void distance_SameLon() {
assertDoesNotThrow(
() -> {
GPS.distance(5, 3, 7, 3);
}
);
}
@Test
public void distance_SamePoint() {
assertEquals(0.0, GPS.distance(5, 3, 5, 3) );
}
@Test
public void distance_SamePoint() {
assertEquals(0.0, GPS.distance(5, 3, 5, 3));
}
@Test
public void distance_NegativePoint(){
assertNotEquals(0.0, GPS.distance(-5, 7, -13, 4));
}
@Test
public void distance_NegativePoint() {
assertNotEquals(0.0, GPS.distance(-5, 7, -13, 4));
}
}