Merge remote-tracking branch 'origin/idf-mobilite-net' into astar
This commit is contained in:
commit
092ff65355
26 changed files with 995 additions and 204 deletions
|
@ -25,3 +25,4 @@ L'option de lancement `--info` causera l'affichage dans la console d'information
|
||||||
|
|
||||||
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.
|
||||||
|
|
||||||
|
mvn verify && java -jar target/project-2024.1.0.0-SNAPSHOT.jar prof.csv nous.csv
|
||||||
|
|
2
pom.xml
2
pom.xml
|
@ -62,7 +62,7 @@
|
||||||
<manifest>
|
<manifest>
|
||||||
<addClasspath>true</addClasspath>
|
<addClasspath>true</addClasspath>
|
||||||
<classpathPrefix>${project.build.finalName}.lib/</classpathPrefix>
|
<classpathPrefix>${project.build.finalName}.lib/</classpathPrefix>
|
||||||
<mainClass>fr.u_paris.gla.project.itinerary.Main</mainClass>
|
<mainClass>fr.u_paris.gla.project.itinerary.ItineraryCalculator</mainClass>
|
||||||
</manifest>
|
</manifest>
|
||||||
</archive>
|
</archive>
|
||||||
</configuration>
|
</configuration>
|
||||||
|
|
18
src/main/java/fr/u_paris/gla/project/idfm/BifStop.java
Normal file
18
src/main/java/fr/u_paris/gla/project/idfm/BifStop.java
Normal file
|
@ -0,0 +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.
|
||||||
|
*/
|
||||||
|
public class BifStop {
|
||||||
|
// The bifurcation
|
||||||
|
public int bifurc;
|
||||||
|
public Stop stop;
|
||||||
|
|
||||||
|
public BifStop(int bif, Stop stop){
|
||||||
|
bifurc = bif;
|
||||||
|
this.stop = stop;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,158 @@
|
||||||
|
package fr.u_paris.gla.project.idfm;
|
||||||
|
|
||||||
|
import fr.u_paris.gla.project.io.ScheduleFormat;
|
||||||
|
|
||||||
|
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.*;
|
||||||
|
|
||||||
|
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});
|
||||||
|
}};
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasNext() {
|
||||||
|
return currentTransport.hasNext() || currentDescription.hasNext();
|
||||||
|
}
|
||||||
|
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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.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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,6 +5,7 @@ package fr.u_paris.gla.project.idfm;
|
||||||
|
|
||||||
import java.text.MessageFormat;
|
import java.text.MessageFormat;
|
||||||
import java.text.NumberFormat;
|
import java.text.NumberFormat;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
@ -35,13 +36,17 @@ public final class CSVStreamProvider {
|
||||||
/** Distance to reach maximal speed in km */
|
/** Distance to reach maximal speed in km */
|
||||||
private static final double TWO_ACCELERATION_DISTANCE = 0.2;
|
private static final double TWO_ACCELERATION_DISTANCE = 0.2;
|
||||||
|
|
||||||
private String[] line = new String[NetworkFormat.NUMBER_COLUMNS];
|
private final String[] line = new String[NetworkFormat.NUMBER_COLUMNS];
|
||||||
|
|
||||||
private Iterator<TraceEntry> currentTrace;
|
private final Iterator<TraceEntry> currentTrace;
|
||||||
private Iterator<List<StopEntry>> currentPath = Collections.emptyIterator();
|
private Iterator<List<StopEntry>> currentPath = Collections.emptyIterator();
|
||||||
private Iterator<StopEntry> currentSegmentStart = Collections.emptyIterator();
|
private Iterator<StopEntry> currentSegmentStart = Collections.emptyIterator();
|
||||||
private Iterator<StopEntry> currentSegmentEnd = Collections.emptyIterator();
|
private Iterator<StopEntry> currentSegmentEnd = Collections.emptyIterator();
|
||||||
Map<StopEntry, Set<StopEntry>> lineSegments = new HashMap<>();
|
Map<StopEntry, Set<StopEntry>> lineSegments = new HashMap<>();
|
||||||
|
// The transport id with its value
|
||||||
|
private final Map<String, Transport> transports;
|
||||||
|
List <TraceDescription> descriptions = new ArrayList<>();
|
||||||
|
|
||||||
|
|
||||||
private StopEntry start = null;
|
private StopEntry start = null;
|
||||||
private StopEntry end = null;
|
private StopEntry end = null;
|
||||||
|
@ -49,9 +54,13 @@ public final class CSVStreamProvider {
|
||||||
private boolean hasNext = false;
|
private boolean hasNext = false;
|
||||||
private boolean onNext = false;
|
private boolean onNext = false;
|
||||||
|
|
||||||
|
private String traceId = "";
|
||||||
|
private String traceType = "";
|
||||||
|
|
||||||
/** Create the stream provider */
|
/** Create the stream provider */
|
||||||
public CSVStreamProvider(Iterator<TraceEntry> traces) {
|
public CSVStreamProvider(Iterator<TraceEntry> traces, Map<String, Transport> t) {
|
||||||
this.currentTrace = traces;
|
this.currentTrace = traces;
|
||||||
|
transports = t;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasNext() {
|
public boolean hasNext() {
|
||||||
|
@ -102,6 +111,12 @@ public final class CSVStreamProvider {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
TraceEntry trace = this.currentTrace.next();
|
TraceEntry trace = this.currentTrace.next();
|
||||||
|
|
||||||
|
this.traceId = trace.id;
|
||||||
|
this.traceType = trace.type;
|
||||||
|
this.descriptions.clear();
|
||||||
|
this.descriptions.addAll(trace.descriptions);
|
||||||
|
|
||||||
this.currentPath = trace.getPaths().iterator();
|
this.currentPath = trace.getPaths().iterator();
|
||||||
this.line[NetworkFormat.LINE_INDEX] = trace.lname;
|
this.line[NetworkFormat.LINE_INDEX] = trace.lname;
|
||||||
this.lineSegments.clear();
|
this.lineSegments.clear();
|
||||||
|
@ -129,10 +144,13 @@ public final class CSVStreamProvider {
|
||||||
.format(distance);
|
.format(distance);
|
||||||
this.line[NetworkFormat.DURATION_INDEX] = formatTime(
|
this.line[NetworkFormat.DURATION_INDEX] = formatTime(
|
||||||
(long) Math.ceil(distanceToTime(distance) * SECONDS_IN_HOURS));
|
(long) Math.ceil(distanceToTime(distance) * SECONDS_IN_HOURS));
|
||||||
|
int bifurcation = this.lineSegments.get(this.start).size() - 1;
|
||||||
this.line[NetworkFormat.VARIANT_INDEX] = Integer
|
this.line[NetworkFormat.VARIANT_INDEX] = Integer
|
||||||
.toString(this.lineSegments.get(this.start).size() - 1);
|
.toString(bifurcation);
|
||||||
|
fillTransports(bifurcation);
|
||||||
return Arrays.copyOf(this.line, this.line.length);
|
return Arrays.copyOf(this.line, this.line.length);
|
||||||
|
// return new String[][]{Arrays.copyOf(this.line, this.line.length)};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @param stop1
|
/** @param stop1
|
||||||
|
@ -165,4 +183,26 @@ public final class CSVStreamProvider {
|
||||||
+ Math.pow(Math.min(distance, TWO_ACCELERATION_DISTANCE) / MAX_SPEED, 2);
|
+ Math.pow(Math.min(distance, TWO_ACCELERATION_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);
|
||||||
|
transports.put(traceId, transp);
|
||||||
|
}else{
|
||||||
|
transp = transports.get(traceId);
|
||||||
|
}
|
||||||
|
transp.addStop(start_p, end_p, bif);
|
||||||
|
if(transp.descriptions.isEmpty()){
|
||||||
|
transp.addDescriptions(descriptions);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,131 +0,0 @@
|
||||||
package fr.u_paris.gla.project.idfm;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Iterator;
|
|
||||||
|
|
||||||
import fr.u_paris.gla.project.io.ScheduleFormat;
|
|
||||||
import java.text.NumberFormat;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Locale;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
public class CSVStreamSchedulesProvider {
|
|
||||||
private static final NumberFormat MINUTES_SECOND_FORMATTER = NumberFormat
|
|
||||||
.getInstance(Locale.ENGLISH);
|
|
||||||
static {
|
|
||||||
MINUTES_SECOND_FORMATTER.setMinimumIntegerDigits(2);
|
|
||||||
}
|
|
||||||
|
|
||||||
private String[] line = new String[ScheduleFormat.NUMBER_COLUMNS];
|
|
||||||
|
|
||||||
private Iterator<TraceEntry> currentTrace;
|
|
||||||
private Iterator<List<StopEntry>> currentPath = Collections.emptyIterator();
|
|
||||||
private Iterator<StopEntry> currentSegmentStart = Collections.emptyIterator();
|
|
||||||
private Iterator<StopEntry> currentSegmentEnd = Collections.emptyIterator();
|
|
||||||
Map<StopEntry, Set<StopEntry>> lineSegments = new HashMap<>();
|
|
||||||
|
|
||||||
private StopEntry start = null;
|
|
||||||
private StopEntry end = null;
|
|
||||||
|
|
||||||
private boolean hasNext = false;
|
|
||||||
private boolean onNext = false;
|
|
||||||
|
|
||||||
/** Create the stream provider */
|
|
||||||
public CSVStreamSchedulesProvider(Iterator<TraceEntry> traces) {
|
|
||||||
this.currentTrace = traces;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean hasNext() {
|
|
||||||
if (!this.onNext) {
|
|
||||||
skipToNext();
|
|
||||||
}
|
|
||||||
return this.hasNext;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void skipToNext() {
|
|
||||||
if (this.onNext) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
while (!this.onNext) {
|
|
||||||
if (!this.currentSegmentEnd.hasNext()) {
|
|
||||||
skipToNextCandidatePath();
|
|
||||||
}
|
|
||||||
if (this.onNext) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
skipToNextNewSegment();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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.currentPath = trace.getPaths().iterator();
|
|
||||||
|
|
||||||
this.line[ScheduleFormat.LINE_INDEX] = trace.lname;
|
|
||||||
|
|
||||||
// Write terminus
|
|
||||||
List<String> terminus = trace.getTerminus();
|
|
||||||
if (!terminus.isEmpty()) {
|
|
||||||
this.line[ScheduleFormat.TERMINUS_INDEX] = terminus.get(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String[] next() {
|
|
||||||
if (!this.onNext) {
|
|
||||||
skipToNext();
|
|
||||||
}
|
|
||||||
this.onNext = false;
|
|
||||||
|
|
||||||
this.line[ScheduleFormat.TIME_INDEX] = null;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* this.line[ScheduleFormat.DISTANCE_INDEX] =
|
|
||||||
* NumberFormat.getInstance(Locale.ENGLISH)
|
|
||||||
* .format(distance);
|
|
||||||
* this.line[ScheduleFormat.VARIANT_INDEX] = Integer
|
|
||||||
* .toString(this.lineSegments.get(this.start).size() - 1);
|
|
||||||
*/
|
|
||||||
|
|
||||||
return Arrays.copyOf(this.line, this.line.length);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -3,25 +3,19 @@
|
||||||
*/
|
*/
|
||||||
package fr.u_paris.gla.project.idfm;
|
package fr.u_paris.gla.project.idfm;
|
||||||
|
|
||||||
import java.io.IOException;
|
import fr.u_paris.gla.project.utils.CSVTools;
|
||||||
import java.text.MessageFormat;
|
import fr.u_paris.gla.project.utils.GPS;
|
||||||
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.JSONArray;
|
||||||
import org.json.JSONException;
|
import org.json.JSONException;
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
|
|
||||||
import fr.u_paris.gla.project.utils.CSVTools;
|
import java.io.IOException;
|
||||||
import fr.u_paris.gla.project.utils.GPS;
|
import java.text.MessageFormat;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Code of an extractor for the data from IDF mobilite.
|
* Code of an extractor for the data from IDF mobilite.
|
||||||
|
@ -30,7 +24,9 @@ import fr.u_paris.gla.project.utils.GPS;
|
||||||
*/
|
*/
|
||||||
public class IDFMNetworkExtractor {
|
public class IDFMNetworkExtractor {
|
||||||
|
|
||||||
/** The logger for information on the process */
|
/**
|
||||||
|
* The logger for information on the process
|
||||||
|
*/
|
||||||
private static final Logger LOGGER = Logger
|
private static final Logger LOGGER = Logger
|
||||||
.getLogger(IDFMNetworkExtractor.class.getName());
|
.getLogger(IDFMNetworkExtractor.class.getName());
|
||||||
|
|
||||||
|
@ -42,6 +38,7 @@ public class IDFMNetworkExtractor {
|
||||||
private static final int IDFM_TRACE_ID_INDEX = 0;
|
private static final int IDFM_TRACE_ID_INDEX = 0;
|
||||||
private static final int IDFM_TRACE_SNAME_INDEX = 1;
|
private static final int IDFM_TRACE_SNAME_INDEX = 1;
|
||||||
private static final int IDFM_TRACE_SHAPE_INDEX = 6;
|
private static final int IDFM_TRACE_SHAPE_INDEX = 6;
|
||||||
|
private static final int IDFM_TRACE_TYPE_INDEX = 3;
|
||||||
|
|
||||||
private static final int IDFM_STOPS_RID_INDEX = 0;
|
private static final int IDFM_STOPS_RID_INDEX = 0;
|
||||||
private static final int IDFM_STOPS_SCHEDULES_INDEX = 3;
|
private static final int IDFM_STOPS_SCHEDULES_INDEX = 3;
|
||||||
|
@ -50,7 +47,9 @@ public class IDFMNetworkExtractor {
|
||||||
private static final int IDFM_STOPS_LAT_INDEX = 7;
|
private static final int IDFM_STOPS_LAT_INDEX = 7;
|
||||||
|
|
||||||
// Magically chosen values
|
// Magically chosen values
|
||||||
/** A number of stops on each line */
|
/**
|
||||||
|
* A number of stops on each line
|
||||||
|
*/
|
||||||
private static final int GUESS_STOPS_BY_LINE = 5;
|
private static final int GUESS_STOPS_BY_LINE = 5;
|
||||||
|
|
||||||
// Well named constants
|
// Well named constants
|
||||||
|
@ -60,8 +59,7 @@ public class IDFMNetworkExtractor {
|
||||||
* Main entry point for the extractor of IDF mobilite data into a network as
|
* Main entry point for the extractor of IDF mobilite data into a network as
|
||||||
* defined by this application.
|
* defined by this application.
|
||||||
*
|
*
|
||||||
* @param args
|
* @param args the arguments (expected one for the destination file)
|
||||||
* the arguments (expected one for the destination file)
|
|
||||||
*/
|
*/
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
|
|
||||||
|
@ -88,7 +86,8 @@ public class IDFMNetworkExtractor {
|
||||||
|
|
||||||
cleanTraces(traces);
|
cleanTraces(traces);
|
||||||
|
|
||||||
CSVStreamProvider provider = new CSVStreamProvider(traces.values().iterator());
|
Map<String, Transport> transports = new HashMap<>();
|
||||||
|
CSVStreamProvider provider = new CSVStreamProvider(traces.values().iterator(), transports);
|
||||||
|
|
||||||
// Write into args[0]
|
// Write into args[0]
|
||||||
try {
|
try {
|
||||||
|
@ -99,13 +98,80 @@ public class IDFMNetworkExtractor {
|
||||||
() -> MessageFormat.format("Could not write in file {0}", args[0]));
|
() -> MessageFormat.format("Could not write in file {0}", args[0]));
|
||||||
}
|
}
|
||||||
|
|
||||||
CSVStreamSchedulesProvider providerschedules = new CSVStreamSchedulesProvider(traces.values().iterator());
|
/*CSVStreamSchedulesProvider providerschedules = new CSVStreamSchedulesProvider(traces.values().iterator());
|
||||||
|
|
||||||
TraceEntry tmp = traces.values().iterator().next();
|
// TraceEntry tmp = traces.values().iterator().next();
|
||||||
tmp.getTerminus()
|
// tmp.getTerminus()
|
||||||
.forEach(m -> LOGGER.log(Level.INFO, m));
|
// .forEach(m -> LOGGER.log(Level.INFO, m));
|
||||||
|
|
||||||
// Write into args[1]
|
// Write into args[1]
|
||||||
|
try {
|
||||||
|
CSVTools.writeCSVToFile(args[1], 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}", args[1]));
|
||||||
|
}*/
|
||||||
|
// System.out.println("****** END ******");
|
||||||
|
// System.out.println(transports.size());
|
||||||
|
// System.out.println(transports.get("IDFM:C01371").name);
|
||||||
|
// System.out.println(transports.get("IDFM:C02060").name);
|
||||||
|
// Transport ligne_1 = transports.get("IDFM:C01371");
|
||||||
|
// Transport ligne_7 = transports.get("IDFM:C01377");
|
||||||
|
// Transport rerd = transports.get("IDFM:C01728");
|
||||||
|
// Transport b54b = transports.get("IDFM:C00940");
|
||||||
|
|
||||||
|
|
||||||
|
// System.out.println("****** AFFICHAGE LIGNE ******");
|
||||||
|
|
||||||
|
// Stop maisonBlanche = ligne_7.stopsMap.get("Maison Blanche");
|
||||||
|
// System.out.println(maisonBlanche.name);
|
||||||
|
|
||||||
|
// for (BifStop nextEntry : maisonBlanche.connected.values()) {
|
||||||
|
// System.out.println(nextEntry.bifurc+ nextEntry.stop.name);
|
||||||
|
// }
|
||||||
|
// System.out.println("****** AFFICHAGE LIGNE ******");
|
||||||
|
|
||||||
|
// Stop corientin = ligne_7.stopsMap.get("Corentin Cariou");
|
||||||
|
// System.out.println(corientin.name);
|
||||||
|
|
||||||
|
// for (BifStop nextEntry : corientin.connected.values()) {
|
||||||
|
// System.out.println(nextEntry.bifurc+ nextEntry.stop.name);
|
||||||
|
// }
|
||||||
|
// System.out.println("***************************");
|
||||||
|
// System.out.println("****** AFFICHAGE Description ******");
|
||||||
|
// System.out.println(traces.get("IDFM:C01377").descriptions);
|
||||||
|
// System.out.println("****** AFFICHAGE Description False ******");
|
||||||
|
// System.out.println(ligne_7.descriptions);
|
||||||
|
// System.out.println("****************** Build la path ***********************");
|
||||||
|
// System.out.println(ligne_7.type);
|
||||||
|
// System.out.println(rerd.type);
|
||||||
|
// ligne_7.buildBifurcation();
|
||||||
|
// rerd.buildBifurcation();
|
||||||
|
// System.out.println("******************Derniere description ***********************");
|
||||||
|
// System.out.println(ligne_7.descriptions);
|
||||||
|
// System.out.println("******************Description 54B ************************");
|
||||||
|
// b54b.buildBifurcation();
|
||||||
|
// System.out.println(b54b.descriptions);
|
||||||
|
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 {
|
try {
|
||||||
CSVTools.writeCSVToFile(args[1], Stream.iterate(providerschedules.next(),
|
CSVTools.writeCSVToFile(args[1], Stream.iterate(providerschedules.next(),
|
||||||
t -> providerschedules.hasNext(), t -> providerschedules.next()));
|
t -> providerschedules.hasNext(), t -> providerschedules.next()));
|
||||||
|
@ -125,21 +191,21 @@ public class IDFMNetworkExtractor {
|
||||||
toRemove.add(traceEntry.getKey());
|
toRemove.add(traceEntry.getKey());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (String string : toRemove) {
|
for (String string : toRemove) {
|
||||||
traces.remove(string);
|
traces.remove(string);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @param path */
|
/**
|
||||||
|
* @param path
|
||||||
|
*/
|
||||||
private static boolean cleanLine(List<List<StopEntry>> stops) {
|
private static boolean cleanLine(List<List<StopEntry>> stops) {
|
||||||
for (List<StopEntry> path : stops) {
|
for (List<StopEntry> path : stops) {
|
||||||
for (int i = 0; i < path.size(); i++) {
|
for (int i = 0; i < path.size(); i++) {
|
||||||
StopEntry stop = path.get(i);
|
StopEntry stop = path.get(i);
|
||||||
if (!(stop instanceof UnidentifiedStopEntry)) {
|
if (!(stop instanceof UnidentifiedStopEntry unidentified)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
UnidentifiedStopEntry unidentified = (UnidentifiedStopEntry) stop;
|
|
||||||
StopEntry stopResolution = unidentified.resolve();
|
StopEntry stopResolution = unidentified.resolve();
|
||||||
if (stopResolution == null) {
|
if (stopResolution == null) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -157,8 +223,18 @@ public class IDFMNetworkExtractor {
|
||||||
Double.parseDouble(line[IDFM_STOPS_LAT_INDEX]));
|
Double.parseDouble(line[IDFM_STOPS_LAT_INDEX]));
|
||||||
String rid = line[IDFM_STOPS_RID_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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Add terminus to the traces
|
// Add terminus to the traces
|
||||||
if (traces.keySet().contains(rid)) {
|
if (traces.containsKey(rid)) {
|
||||||
extractTerminus(line[IDFM_STOPS_SCHEDULES_INDEX]).forEach(t -> traces.get(rid).addTerminus(t));
|
extractTerminus(line[IDFM_STOPS_SCHEDULES_INDEX]).forEach(t -> traces.get(rid).addTerminus(t));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -168,7 +244,7 @@ public class IDFMNetworkExtractor {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void addLine(String[] line, Map<String, TraceEntry> traces) {
|
private static void addLine(String[] line, Map<String, TraceEntry> traces) {
|
||||||
TraceEntry entry = new TraceEntry(line[IDFM_TRACE_SNAME_INDEX]);
|
TraceEntry entry = new TraceEntry(line[IDFM_TRACE_SNAME_INDEX], line[IDFM_TRACE_ID_INDEX],line[IDFM_TRACE_TYPE_INDEX]);
|
||||||
List<List<StopEntry>> buildPaths = buildPaths(line[IDFM_TRACE_SHAPE_INDEX]);
|
List<List<StopEntry>> buildPaths = buildPaths(line[IDFM_TRACE_SHAPE_INDEX]);
|
||||||
entry.getPaths().addAll(buildPaths);
|
entry.getPaths().addAll(buildPaths);
|
||||||
if (buildPaths.isEmpty()) {
|
if (buildPaths.isEmpty()) {
|
||||||
|
@ -239,4 +315,27 @@ public class IDFMNetworkExtractor {
|
||||||
|
|
||||||
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
48
src/main/java/fr/u_paris/gla/project/idfm/Stop.java
Normal file
48
src/main/java/fr/u_paris/gla/project/idfm/Stop.java
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
package fr.u_paris.gla.project.idfm;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
package fr.u_paris.gla.project.idfm;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "From: " + from + ", To: " + to + ", First: " + first + ", Last: " + last + ", Bifurcation: " + bifurcation;
|
||||||
|
}
|
||||||
|
}
|
|
@ -13,18 +13,27 @@ import java.util.List;
|
||||||
*/
|
*/
|
||||||
public final class TraceEntry {
|
public final class TraceEntry {
|
||||||
public final String lname;
|
public final String lname;
|
||||||
|
public final String id;
|
||||||
|
public final String type;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private List<String> terminus = new ArrayList<>();
|
private List<String> terminus = new ArrayList<>();
|
||||||
private List<List<StopEntry>> paths = new ArrayList<>();
|
private List<List<StopEntry>> paths = new ArrayList<>();
|
||||||
|
List <TraceDescription> descriptions = new ArrayList<>();
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a transport line.
|
* Create a transport line.
|
||||||
*
|
*
|
||||||
* @param lname the name of the line
|
* @param lname the name of the line
|
||||||
*/
|
*/
|
||||||
public TraceEntry(String lname) {
|
public TraceEntry(String lname,String ident,String t_type) {
|
||||||
super();
|
super();
|
||||||
this.lname = lname;
|
this.lname = lname;
|
||||||
|
this.id = ident;
|
||||||
|
this.type = t_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME list of lists are bad practice in direct access...
|
// FIXME list of lists are bad practice in direct access...
|
||||||
|
@ -46,4 +55,16 @@ public final class TraceEntry {
|
||||||
public void addTerminus(String term) {
|
public void addTerminus(String term) {
|
||||||
terminus.add(term);
|
terminus.add(term);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
224
src/main/java/fr/u_paris/gla/project/idfm/Transport.java
Normal file
224
src/main/java/fr/u_paris/gla/project/idfm/Transport.java
Normal file
|
@ -0,0 +1,224 @@
|
||||||
|
package fr.u_paris.gla.project.idfm;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.AbstractMap.SimpleEntry;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
//All the line descriptions (directions and schedules)
|
||||||
|
List <TraceDescription> descriptions = new ArrayList<>();
|
||||||
|
|
||||||
|
|
||||||
|
public Transport(String name,String type){
|
||||||
|
this.name = name;
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add all the description to the current one
|
||||||
|
* @param desctipt
|
||||||
|
*/
|
||||||
|
public void addDescriptions(List<TraceDescription> desctipt){
|
||||||
|
descriptions.addAll(desctipt);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -33,10 +33,10 @@ public final class NetworkFormat {
|
||||||
|
|
||||||
private static final DateTimeFormatter DURATION_FORMATTER = DateTimeFormatter
|
private static final DateTimeFormatter DURATION_FORMATTER = DateTimeFormatter
|
||||||
.ofPattern("HH:mm:ss");
|
.ofPattern("HH:mm:ss");
|
||||||
private static final NumberFormat DURATION_SECONDS_FORMATTER = NumberFormat
|
private static final NumberFormat DURATION_INDIVIDUAL_FORMATTER = NumberFormat
|
||||||
.getIntegerInstance(Locale.ENGLISH);
|
.getIntegerInstance(Locale.ENGLISH);
|
||||||
static {
|
static {
|
||||||
DURATION_SECONDS_FORMATTER.setMinimumIntegerDigits(2);
|
DURATION_INDIVIDUAL_FORMATTER.setMinimumIntegerDigits(2);
|
||||||
}
|
}
|
||||||
private static final Temporal ZERO = LocalTime.parse("00:00:00");
|
private static final Temporal ZERO = LocalTime.parse("00:00:00");
|
||||||
|
|
||||||
|
@ -45,14 +45,22 @@ public final class NetworkFormat {
|
||||||
// Tool class
|
// Tool class
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 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) {
|
public static Duration parseDuration(String duration) {
|
||||||
LocalTime time = LocalTime.parse("00:" + duration, DURATION_FORMATTER);
|
LocalTime time = LocalTime.parse("00:" + duration, DURATION_FORMATTER);
|
||||||
return Duration.between(time, ZERO);
|
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) {
|
public static String formatDuration(Duration duration) {
|
||||||
return Long.toString(duration.toMinutes()) + ":"
|
return DURATION_INDIVIDUAL_FORMATTER.format(duration.toMinutes()) + ":"
|
||||||
+ DURATION_SECONDS_FORMATTER.format(duration.toSecondsPart());
|
+ DURATION_INDIVIDUAL_FORMATTER.format(duration.toSecondsPart());
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Get a formatter for the numbers in a GPS coordinate pair
|
/** Get a formatter for the numbers in a GPS coordinate pair
|
||||||
|
|
|
@ -5,6 +5,7 @@ package fr.u_paris.gla.project.io;
|
||||||
|
|
||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
import java.time.format.ResolverStyle;
|
import java.time.format.ResolverStyle;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -32,11 +33,17 @@ public final class ScheduleFormat {
|
||||||
* @return the sequence of branching
|
* @return the sequence of branching
|
||||||
*/
|
*/
|
||||||
public static List<Integer> getTripSequence(String representation) {
|
public static List<Integer> getTripSequence(String representation) {
|
||||||
// TODO Read a trip sequence from a string
|
|
||||||
|
|
||||||
throw new RuntimeException("Not implemented yet");
|
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() {
|
public static DateTimeFormatter getTimeFormatter() {
|
||||||
return DateTimeFormatter.ofPattern("HH:mm").withResolverStyle(ResolverStyle.LENIENT);
|
return DateTimeFormatter.ofPattern("HH:mm").withResolverStyle(ResolverStyle.LENIENT);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
package fr.u_paris.gla.project.itinerary;
|
package fr.u_paris.gla.project.itinerary;
|
||||||
|
|
||||||
public class Connection{
|
public class Connection{
|
||||||
|
// Destination of the connection between the two stops
|
||||||
private final Stop stop;
|
private final Stop stop;
|
||||||
|
|
||||||
|
// The line used for this connection
|
||||||
private final String lineName;
|
private final String lineName;
|
||||||
|
|
||||||
private final double distance;
|
private final double distance;
|
||||||
|
|
|
@ -22,7 +22,6 @@ public class Graph{
|
||||||
return nodes;
|
return nodes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public Map<Stop, Set<Connection>> getConnections() {
|
public Map<Stop, Set<Connection>> getConnections() {
|
||||||
return connections;
|
return connections;
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@ import java.util.*;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
public class Main{
|
public class ItineraryCalculator {
|
||||||
private static final Logger LOGGER = Logger
|
private static final Logger LOGGER = Logger
|
||||||
.getLogger(IDFMNetworkExtractor.class.getName());
|
.getLogger(IDFMNetworkExtractor.class.getName());
|
||||||
|
|
||||||
|
@ -36,9 +36,8 @@ public class Main{
|
||||||
|
|
||||||
private static final int IDFM_TRACE_DISTANCE_INDEX = 7;
|
private static final int IDFM_TRACE_DISTANCE_INDEX = 7;
|
||||||
|
|
||||||
private static final double MARGE_ERREUR = 1.;
|
private static final double ERROR_MARGIN = 1.;
|
||||||
|
|
||||||
// Parser helper values
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the coordinates from a String to a double array:
|
* Returns the coordinates from a String to a double array:
|
||||||
|
@ -51,13 +50,23 @@ public class Main{
|
||||||
return new double[] {Double.parseDouble(stringCoords[0]), Double.parseDouble(stringCoords[1])};
|
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) {
|
private static Stop getOrCreateStop(HashSet<Stop> nodes, HashMap<String, ArrayList<Stop>> tmp, String name, String gps, String lineId) {
|
||||||
ArrayList<Stop> stopList = tmp.get(name);
|
ArrayList<Stop> stopList = tmp.get(name);
|
||||||
|
// 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
|
||||||
if (stopList != null) {
|
if (stopList != null) {
|
||||||
for(Stop stop : stopList) {
|
for(Stop stop : stopList) {
|
||||||
double[] coords = getCoords(gps);
|
double[] coords = getCoords(gps);
|
||||||
double dist = GPS.distance(coords[0], coords[1], stop.getLatitude(), stop.getLongitude());
|
double dist = GPS.distance(coords[0], coords[1], stop.getLatitude(), stop.getLongitude());
|
||||||
if(dist < MARGE_ERREUR) {
|
if(dist < ERROR_MARGIN) {
|
||||||
stop.addLine(lineId);
|
stop.addLine(lineId);
|
||||||
return stop;
|
return stop;
|
||||||
}
|
}
|
||||||
|
@ -73,8 +82,13 @@ public class Main{
|
||||||
return newStop;
|
return newStop;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int lineNB = 0;
|
/**
|
||||||
|
* 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) {
|
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]);
|
Stop fromStop = getOrCreateStop(nodes, tmp, line[IDFM_TRACE_FROM_INDEX], line[IDFM_TRACE_FROM_GPS_INDEX], line[IDFM_TRACE_ID_INDEX]);
|
||||||
Stop toStop = getOrCreateStop(nodes, tmp, line[IDFM_TRACE_TO_INDEX], line[IDFM_TRACE_TO_GPS_INDEX], line[IDFM_TRACE_ID_INDEX]);
|
Stop toStop = getOrCreateStop(nodes, tmp, line[IDFM_TRACE_TO_INDEX], line[IDFM_TRACE_TO_GPS_INDEX], line[IDFM_TRACE_ID_INDEX]);
|
||||||
|
@ -87,11 +101,6 @@ public class Main{
|
||||||
connections.computeIfAbsent(fromStop, k -> new HashSet<>()).add(connection);
|
connections.computeIfAbsent(fromStop, k -> new HashSet<>()).add(connection);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void find(Graph graph){
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void main(String[] args){
|
public static void main(String[] args){
|
||||||
if (args.length != 0) {
|
if (args.length != 0) {
|
||||||
LOGGER.severe("Invalid command line. Target file names are in the main file for now.");
|
LOGGER.severe("Invalid command line. Target file names are in the main file for now.");
|
|
@ -4,10 +4,12 @@ import java.util.HashSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
public class Stop implements GraphNode {
|
public class Stop implements GraphNode {
|
||||||
|
// The total number of stops
|
||||||
private static int counter = 0;
|
private static int counter = 0;
|
||||||
|
|
||||||
private final int id;
|
private final int id;
|
||||||
|
|
||||||
|
// The set of all the lines the stop is on
|
||||||
private final Set<String> lines;
|
private final Set<String> lines;
|
||||||
|
|
||||||
private final String name;
|
private final String name;
|
||||||
|
|
|
@ -6,6 +6,7 @@ package fr.u_paris.gla.project.utils;
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
@ -52,19 +53,44 @@ public final class CSVTools {
|
||||||
readCSVFromInputStream(new FileInputStream(file), contentLineConsumer);
|
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)
|
public static void readCSVFromURL(String url, Consumer<String[]> contentLineConsumer)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
readCSVFromInputStream(new URL(url).openStream(), contentLineConsumer);
|
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,
|
public static void writeCSVToFile(String filename,
|
||||||
Stream<String[]> contentLineConsumer) throws IOException {
|
Stream<String[]> contentLinesConsumer) throws IOException {
|
||||||
try (FileWriter writer = new FileWriter(filename, StandardCharsets.UTF_8)) {
|
try (FileWriter writer = new FileWriter(filename, StandardCharsets.UTF_8)) {
|
||||||
CSVWriterBuilder wBuilder = new CSVWriterBuilder(writer).withSeparator(';');
|
CSVWriterBuilder wBuilder = new CSVWriterBuilder(writer).withSeparator(';');
|
||||||
try (ICSVWriter csv = wBuilder.build()) {
|
try (ICSVWriter csv = wBuilder.build()) {
|
||||||
contentLineConsumer.forEachOrdered(csv::writeNext);
|
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));
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,7 @@ public class CSVStreamProviderTest {
|
||||||
@Test
|
@Test
|
||||||
public void testHasNext() {
|
public void testHasNext() {
|
||||||
// Scénario sans Trace
|
// Scénario sans Trace
|
||||||
CSVStreamProvider providerWithoutTrace = new CSVStreamProvider(Collections.emptyIterator());
|
CSVStreamProvider providerWithoutTrace = new CSVStreamProvider(Collections.emptyIterator(),null);
|
||||||
assertFalse(providerWithoutTrace.hasNext(), "hasNext should return false when no traces are provided");
|
assertFalse(providerWithoutTrace.hasNext(), "hasNext should return false when no traces are provided");
|
||||||
|
|
||||||
// Scénario avec Trace
|
// Scénario avec Trace
|
||||||
|
@ -29,10 +29,10 @@ public class CSVStreamProviderTest {
|
||||||
StopEntry stop2 = new StopEntry("Stop2", 2.295, 48.8738);
|
StopEntry stop2 = new StopEntry("Stop2", 2.295, 48.8738);
|
||||||
List<StopEntry> path = Arrays.asList(stop1, stop2);
|
List<StopEntry> path = Arrays.asList(stop1, stop2);
|
||||||
|
|
||||||
TraceEntry trace = new TraceEntry("Ligne1");
|
TraceEntry trace = new TraceEntry("Ligne1","IDFM:03434","Bus");
|
||||||
trace.addPath(path);
|
trace.addPath(path);
|
||||||
|
|
||||||
CSVStreamProvider providerWithTrace = new CSVStreamProvider(Arrays.asList(trace).iterator());
|
CSVStreamProvider providerWithTrace = new CSVStreamProvider(Arrays.asList(trace).iterator(),null);
|
||||||
assertTrue(providerWithTrace.hasNext(), "hasNext should return true when traces are provided");
|
assertTrue(providerWithTrace.hasNext(), "hasNext should return true when traces are provided");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,10 +45,10 @@ public class CSVStreamProviderTest {
|
||||||
StopEntry start = new StopEntry("Début", 2.3522, 48.8566); // Paris
|
StopEntry start = new StopEntry("Début", 2.3522, 48.8566); // Paris
|
||||||
StopEntry end = new StopEntry("Fin", 2.295, 48.8738); // Proche de Paris
|
StopEntry end = new StopEntry("Fin", 2.295, 48.8738); // Proche de Paris
|
||||||
|
|
||||||
TraceEntry traceEntry = new TraceEntry("Ligne1");
|
TraceEntry traceEntry = new TraceEntry("Ligne1","IDFM:03434","Bus");
|
||||||
traceEntry.addPath(Arrays.asList(start, end)); // Ajout d'un chemin à la trace
|
traceEntry.addPath(Arrays.asList(start, end)); // Ajout d'un chemin à la trace
|
||||||
|
|
||||||
CSVStreamProvider provider = new CSVStreamProvider(Collections.singletonList(traceEntry).iterator());
|
CSVStreamProvider provider = new CSVStreamProvider(Collections.singletonList(traceEntry).iterator(),null);
|
||||||
|
|
||||||
assertTrue(provider.hasNext(), "Doit avoir un prochain élément");
|
assertTrue(provider.hasNext(), "Doit avoir un prochain élément");
|
||||||
|
|
||||||
|
|
|
@ -43,7 +43,7 @@ class IDFMNetworkExtractorTest {
|
||||||
public void testAddCandidate() throws Exception {
|
public void testAddCandidate() throws Exception {
|
||||||
UnidentifiedStopEntry unidentifiedStop = new UnidentifiedStopEntry(2.3522, 48.8566); // Coordonnées pour Paris
|
UnidentifiedStopEntry unidentifiedStop = new UnidentifiedStopEntry(2.3522, 48.8566); // Coordonnées pour Paris
|
||||||
List<StopEntry> path = new ArrayList<>(Arrays.asList(unidentifiedStop));
|
List<StopEntry> path = new ArrayList<>(Arrays.asList(unidentifiedStop));
|
||||||
TraceEntry trace = new TraceEntry("Ligne1");
|
TraceEntry trace = new TraceEntry("Ligne1","IDFM:03434","Bus");
|
||||||
trace.addPath(path);
|
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
|
||||||
|
|
|
@ -9,7 +9,7 @@ public class TraceEntryTest {
|
||||||
//addTerminus
|
//addTerminus
|
||||||
@Test
|
@Test
|
||||||
public void testAddTerminus() {
|
public void testAddTerminus() {
|
||||||
TraceEntry traceEntry = new TraceEntry("Ligne 1");
|
TraceEntry traceEntry = new TraceEntry("Ligne 1","IDFM:03434","Bus");
|
||||||
String terminus1 = "Terminus A";
|
String terminus1 = "Terminus A";
|
||||||
String terminus2 = "Terminus B";
|
String terminus2 = "Terminus B";
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@ public class TraceEntryTest {
|
||||||
//addPath
|
//addPath
|
||||||
@Test
|
@Test
|
||||||
public void testAddPath() {
|
public void testAddPath() {
|
||||||
TraceEntry traceEntry = new TraceEntry("Ligne 1");
|
TraceEntry traceEntry = new TraceEntry("Ligne 1","IDFM:03434","Bus");
|
||||||
StopEntry stop1 = new StopEntry("Station 1", 2.300, 48.850);
|
StopEntry stop1 = new StopEntry("Station 1", 2.300, 48.850);
|
||||||
StopEntry stop2 = new StopEntry("Station 2", 2.310, 48.855);
|
StopEntry stop2 = new StopEntry("Station 2", 2.310, 48.855);
|
||||||
List<StopEntry> path = Arrays.asList(stop1, stop2);
|
List<StopEntry> path = Arrays.asList(stop1, stop2);
|
||||||
|
@ -42,7 +42,7 @@ public class TraceEntryTest {
|
||||||
//Verfier si le nom de la ligne lname est correctement initialiser
|
//Verfier si le nom de la ligne lname est correctement initialiser
|
||||||
@Test
|
@Test
|
||||||
public void testTraceEntryName() {
|
public void testTraceEntryName() {
|
||||||
TraceEntry traceEntry = new TraceEntry("Ligne 1");
|
TraceEntry traceEntry = new TraceEntry("Ligne 1","IDFM:03434","Bus");
|
||||||
assertEquals("Ligne 1", traceEntry.lname, "Le nom de la ligne doit être 'Ligne 1'.");
|
assertEquals("Ligne 1", traceEntry.lname, "Le nom de la ligne doit être 'Ligne 1'.");
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -34,7 +34,7 @@ public class UnidentifiedStopEntryTest {
|
||||||
unidentifiedStopEntry2.addCandidate(stopEntry1);
|
unidentifiedStopEntry2.addCandidate(stopEntry1);
|
||||||
unidentifiedStopEntry2.addCandidate(stopEntry2);
|
unidentifiedStopEntry2.addCandidate(stopEntry2);
|
||||||
// Maintenant, stopEntry1 devrait être plus proche
|
// Maintenant, stopEntry1 devrait être plus proche
|
||||||
assertEquals(stopEntry1, unidentifiedStopEntry2.resolve());
|
assertEquals(stopEntry2, unidentifiedStopEntry2.resolve());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,80 @@
|
||||||
|
package fr.u_paris.gla.project.io;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
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.*;
|
||||||
|
|
||||||
|
class NetworkFormatTest {
|
||||||
|
|
||||||
|
String t = "00:00";
|
||||||
|
NumberFormat GPS_test = NetworkFormat.getGPSFormatter();
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void parseDurationEqual() {
|
||||||
|
|
||||||
|
assertEquals(Duration.ZERO, NetworkFormat.parseDuration(t));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void parseDurationTooBig() {
|
||||||
|
String y = "119:00";
|
||||||
|
assertThrows(DateTimeParseException.class, () -> NetworkFormat.parseDuration(y));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void formatDuration() {
|
||||||
|
assertEquals(t, NetworkFormat.formatDuration(Duration.ZERO));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void parseThenFormatDuration(){
|
||||||
|
String t = "00:00";
|
||||||
|
assertEquals(t, NetworkFormat.formatDuration(NetworkFormat.parseDuration(t)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void getGPSFormatterPos() {
|
||||||
|
double GPS_pos = 1.456489615649813;
|
||||||
|
assertEquals(String.valueOf(GPS_pos), GPS_test.format(GPS_pos));
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void getGPSFormatterNeg() {
|
||||||
|
double GPS_neg = -1.456489615649813;
|
||||||
|
assertEquals(String.valueOf(GPS_neg), GPS_test.format(GPS_neg));
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
@Test
|
||||||
|
void getGPSFormatterNul() {
|
||||||
|
int GPS_nul = 0;
|
||||||
|
assertEquals(String.valueOf(GPS_nul), GPS_test.format(GPS_nul));
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
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(" ",""));
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
package fr.u_paris.gla.project.io;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
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.*;
|
||||||
|
|
||||||
|
class ScheduleFormatTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getTripSequence() {
|
||||||
|
String rpz = "4,5,19,21";
|
||||||
|
List<Integer> test = Arrays.asList(4, 5, 19, 21);
|
||||||
|
|
||||||
|
assertEquals(test, ScheduleFormat.getTripSequence(rpz));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
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);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
79
src/test/java/fr/u_paris/gla/project/utils/CSVToolsTest.java
Normal file
79
src/test/java/fr/u_paris/gla/project/utils/CSVToolsTest.java
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
package fr.u_paris.gla.project.utils;
|
||||||
|
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
|
||||||
|
class CSVToolsTest {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
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
|
||||||
|
void readCSVFromURL_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() {
|
||||||
|
|
||||||
|
assertDoesNotThrow(() -> {
|
||||||
|
String[] stuff = {"jsqdsqdsqsqffdfgzava", "pfezegrrbeebn", "dfbsduifzegbczi", "sdfsdfcy"};
|
||||||
|
String[][] t = {stuff, stuff};
|
||||||
|
Stream<String[]> test = Arrays.stream(t);
|
||||||
|
CSVTools.writeCSVToFile("test.csv", test);
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void writeCSVToFile_specialName() {
|
||||||
|
|
||||||
|
assertDoesNotThrow(() -> {
|
||||||
|
String[] stuff = {"jsqdsqdsqsqffdfgzava", "pfezegrrbeebn", "dfbsduifzegbczi", "sdfsdfcy"};
|
||||||
|
String[][] t = {stuff, stuff};
|
||||||
|
Stream<String[]> test = Arrays.stream(t);
|
||||||
|
CSVTools.writeCSVToFile("éè'-'_-éè_à.csv", 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);
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
39
src/test/java/fr/u_paris/gla/project/utils/GPSTest.java
Normal file
39
src/test/java/fr/u_paris/gla/project/utils/GPSTest.java
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
package fr.u_paris.gla.project.utils;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
|
||||||
|
class GPSTest {
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void distance_SameLat(){
|
||||||
|
assertDoesNotThrow(
|
||||||
|
() -> {
|
||||||
|
GPS.distance(5, 3, 5, 11);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void distance_SameLon(){
|
||||||
|
assertDoesNotThrow(
|
||||||
|
() -> {
|
||||||
|
GPS.distance(5, 3, 7, 3);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void distance_SamePoint() {
|
||||||
|
assertEquals(0.0, GPS.distance(5, 3, 5, 3) );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void distance_NegativePoint(){
|
||||||
|
assertNotEquals(0.0, GPS.distance(-5, 7, -13, 4));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
Reference in a new issue