Merge branch 'horraires' into 'idf-mobilite-net'
Schedule data implementation See merge request gla-groupe-3/projet!7
This commit is contained in:
commit
62fd2e8bcd
11 changed files with 660 additions and 175 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.
|
||||
|
||||
mvn verify && java -jar target/project-2024.1.0.0-SNAPSHOT.jar prof.csv nous.csv
|
||||
|
|
11
src/main/java/fr/u_paris/gla/project/idfm/BifStop.java
Normal file
11
src/main/java/fr/u_paris/gla/project/idfm/BifStop.java
Normal file
|
@ -0,0 +1,11 @@
|
|||
package fr.u_paris.gla.project.idfm;
|
||||
|
||||
public class BifStop {
|
||||
public int bifurc;
|
||||
public Stop stop;
|
||||
|
||||
public BifStop(int bif, Stop s){
|
||||
bifurc = bif;
|
||||
stop = s;
|
||||
}
|
||||
}
|
|
@ -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.*;
|
||||
|
||||
import org.apache.commons.lang3.ObjectUtils.Null;
|
||||
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[]{45, 50});
|
||||
// put("Funicular", new int[]{120, 70});
|
||||
// put("Tram", new int[]{72, 60});
|
||||
// put("Rail", new int[]{120, 60,50});
|
||||
// put("Subway", new int[]{50, 45});
|
||||
// }};
|
||||
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 int DEFAULT_TIMING = 6;
|
||||
// private static int MINUTES_BEFORE_LAST_DEPARTURE = 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();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void skipToNextDescription() {
|
||||
if (this.currentDescription.hasNext()) {
|
||||
TraceDescription description = this.currentDescription.next();
|
||||
// hours_count = 0;
|
||||
// current_time = description.first;
|
||||
// last_time = description.last;
|
||||
currentHour = convertIntoLocalDateTime(description.first);
|
||||
lastHour = convertIntoLocalDateTime(description.last);
|
||||
// System.out.println("** SkipTOnextD: last hour est "+lastHour+" first est "+currentHour+" desc.last est "+description.last+ " et desc.first est "+description.first);
|
||||
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
private void skipToNextTransport() {
|
||||
if (this.currentTransport.hasNext()) {
|
||||
Transport transport = this.currentTransport.next();
|
||||
this.line[ScheduleFormat.LINE_INDEX] = transport.name;
|
||||
// System.out.println("Changement de transport"+transport.name);
|
||||
|
||||
// transport.buildBifurcation();
|
||||
current_tansport_type = transport.type;
|
||||
this.currentDescription = transport.descriptions.iterator();
|
||||
skipToNextDescription();
|
||||
} else {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public String[][] next() {
|
||||
if (!hasNext()) {
|
||||
return null;
|
||||
}
|
||||
skipToNext();
|
||||
return new String[][]{Arrays.copyOf(this.line, this.line.length)};
|
||||
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
private static long calculateDuration(String debut, String dernier) {
|
||||
LocalTime debutTime = LocalTime.parse(debut, HOUR_MINUTE_FORMATTER);
|
||||
LocalTime dernierTime = LocalTime.parse(dernier, HOUR_MINUTE_FORMATTER);
|
||||
|
||||
Duration difference = Duration.between(debutTime, dernierTime);
|
||||
return difference.toMinutes();
|
||||
}
|
||||
|
||||
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];
|
||||
}
|
||||
|
||||
public static LocalDateTime convertIntoLocalDateTime(String heureMinute) {
|
||||
LocalDateTime aujourdHui = LocalDateTime.now();
|
||||
LocalTime time = LocalTime.parse(heureMinute, 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.NumberFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
|
@ -35,13 +36,17 @@ public final class CSVStreamProvider {
|
|||
/** Distance to reach maximal speed in km */
|
||||
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<StopEntry> currentSegmentStart = Collections.emptyIterator();
|
||||
private Iterator<StopEntry> currentSegmentEnd = Collections.emptyIterator();
|
||||
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 end = null;
|
||||
|
@ -49,9 +54,13 @@ public final class CSVStreamProvider {
|
|||
private boolean hasNext = false;
|
||||
private boolean onNext = false;
|
||||
|
||||
private String traceId = "";
|
||||
private String traceType = "";
|
||||
|
||||
/** Create the stream provider */
|
||||
public CSVStreamProvider(Iterator<TraceEntry> traces) {
|
||||
public CSVStreamProvider(Iterator<TraceEntry> traces, Map<String, Transport> t) {
|
||||
this.currentTrace = traces;
|
||||
transports = t;
|
||||
}
|
||||
|
||||
public boolean hasNext() {
|
||||
|
@ -102,6 +111,12 @@ public final class CSVStreamProvider {
|
|||
return;
|
||||
}
|
||||
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.line[NetworkFormat.LINE_INDEX] = trace.lname;
|
||||
this.lineSegments.clear();
|
||||
|
@ -115,7 +130,7 @@ public final class CSVStreamProvider {
|
|||
} while (currentSegmentStart == null);
|
||||
}
|
||||
|
||||
public String[] next() {
|
||||
public String[][] next() {
|
||||
if (!this.onNext) {
|
||||
skipToNext();
|
||||
}
|
||||
|
@ -129,10 +144,11 @@ public final class CSVStreamProvider {
|
|||
.format(distance);
|
||||
this.line[NetworkFormat.DURATION_INDEX] = formatTime(
|
||||
(long) Math.ceil(distanceToTime(distance) * SECONDS_IN_HOURS));
|
||||
int bifurcation = this.lineSegments.get(this.start).size() - 1;
|
||||
this.line[NetworkFormat.VARIANT_INDEX] = Integer
|
||||
.toString(this.lineSegments.get(this.start).size() - 1);
|
||||
|
||||
return Arrays.copyOf(this.line, this.line.length);
|
||||
.toString(bifurcation);
|
||||
fillTransports(bifurcation);
|
||||
return new String[][]{Arrays.copyOf(this.line, this.line.length)};
|
||||
}
|
||||
|
||||
/** @param stop1
|
||||
|
@ -165,4 +181,23 @@ public final class CSVStreamProvider {
|
|||
+ Math.pow(Math.min(distance, TWO_ACCELERATION_DISTANCE) / MAX_SPEED, 2);
|
||||
}
|
||||
|
||||
private void fillTransports(int bif) {
|
||||
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;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.text.MessageFormat;
|
||||
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 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 fr.u_paris.gla.project.utils.CSVTools;
|
||||
import fr.u_paris.gla.project.utils.GPS;
|
||||
import java.io.IOException;
|
||||
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.
|
||||
|
@ -30,7 +24,9 @@ import fr.u_paris.gla.project.utils.GPS;
|
|||
*/
|
||||
public class IDFMNetworkExtractor {
|
||||
|
||||
/** The logger for information on the process */
|
||||
/**
|
||||
* The logger for information on the process
|
||||
*/
|
||||
private static final Logger LOGGER = Logger
|
||||
.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_SNAME_INDEX = 1;
|
||||
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_SCHEDULES_INDEX = 3;
|
||||
|
@ -50,7 +47,9 @@ public class IDFMNetworkExtractor {
|
|||
private static final int IDFM_STOPS_LAT_INDEX = 7;
|
||||
|
||||
// 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;
|
||||
|
||||
// Well named constants
|
||||
|
@ -60,8 +59,7 @@ public class IDFMNetworkExtractor {
|
|||
* Main entry point for the extractor of IDF mobilite data into a network as
|
||||
* defined by this application.
|
||||
*
|
||||
* @param args
|
||||
* the arguments (expected one for the destination file)
|
||||
* @param args the arguments (expected one for the destination file)
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
|
||||
|
@ -88,7 +86,8 @@ public class IDFMNetworkExtractor {
|
|||
|
||||
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]
|
||||
try {
|
||||
|
@ -99,13 +98,80 @@ public class IDFMNetworkExtractor {
|
|||
() -> 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();
|
||||
tmp.getTerminus()
|
||||
.forEach(m -> LOGGER.log(Level.INFO, m));
|
||||
// TraceEntry tmp = traces.values().iterator().next();
|
||||
// tmp.getTerminus()
|
||||
// .forEach(m -> LOGGER.log(Level.INFO, m));
|
||||
|
||||
// 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 {
|
||||
CSVTools.writeCSVToFile(args[1], Stream.iterate(providerschedules.next(),
|
||||
t -> providerschedules.hasNext(), t -> providerschedules.next()));
|
||||
|
@ -125,21 +191,21 @@ public class IDFMNetworkExtractor {
|
|||
toRemove.add(traceEntry.getKey());
|
||||
}
|
||||
}
|
||||
|
||||
for (String string : toRemove) {
|
||||
traces.remove(string);
|
||||
}
|
||||
}
|
||||
|
||||
/** @param path */
|
||||
/**
|
||||
* @param path
|
||||
*/
|
||||
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)) {
|
||||
if (!(stop instanceof UnidentifiedStopEntry unidentified)) {
|
||||
continue;
|
||||
}
|
||||
UnidentifiedStopEntry unidentified = (UnidentifiedStopEntry) stop;
|
||||
StopEntry stopResolution = unidentified.resolve();
|
||||
if (stopResolution == null) {
|
||||
return false;
|
||||
|
@ -151,14 +217,24 @@ public class IDFMNetworkExtractor {
|
|||
}
|
||||
|
||||
private static void addStop(String[] line, Map<String, TraceEntry> traces,
|
||||
List<StopEntry> stops) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 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));
|
||||
}
|
||||
|
||||
|
@ -168,7 +244,7 @@ public class IDFMNetworkExtractor {
|
|||
}
|
||||
|
||||
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]);
|
||||
entry.getPaths().addAll(buildPaths);
|
||||
if (buildPaths.isEmpty()) {
|
||||
|
@ -184,8 +260,8 @@ public class IDFMNetworkExtractor {
|
|||
for (StopEntry stopEntry : path) {
|
||||
if (stopEntry instanceof UnidentifiedStopEntry unidentified
|
||||
&& GPS.distance(entry.latitude, entry.longitude,
|
||||
stopEntry.latitude,
|
||||
stopEntry.longitude) < QUARTER_KILOMETER) {
|
||||
stopEntry.latitude,
|
||||
stopEntry.longitude) < QUARTER_KILOMETER) {
|
||||
unidentified.addCandidate(entry);
|
||||
}
|
||||
}
|
||||
|
@ -231,7 +307,7 @@ public class IDFMNetworkExtractor {
|
|||
}
|
||||
} catch (
|
||||
|
||||
JSONException e) {
|
||||
JSONException e) {
|
||||
// Ignoring invalid element!
|
||||
LOGGER.log(Level.FINE, e,
|
||||
() -> MessageFormat.format("Invalid json element {0}", JSON)); //$NON-NLS-1$
|
||||
|
@ -239,4 +315,27 @@ public class IDFMNetworkExtractor {
|
|||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
52
src/main/java/fr/u_paris/gla/project/idfm/Stop.java
Normal file
52
src/main/java/fr/u_paris/gla/project/idfm/Stop.java
Normal file
|
@ -0,0 +1,52 @@
|
|||
package fr.u_paris.gla.project.idfm;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
||||
public class Stop {
|
||||
|
||||
Map<String, BifStop> connected = new HashMap<>();
|
||||
public String name;
|
||||
|
||||
public Stop(String n){
|
||||
name = n;
|
||||
}
|
||||
|
||||
// public boolean isStopConnected(String stopName) {
|
||||
// // for (BifStop b : connected) {
|
||||
// // if (b.stop.name.equals(stopName)) {
|
||||
// // return true;
|
||||
// // }
|
||||
// // }
|
||||
// // return false;
|
||||
// return getStop(stopName) != null;
|
||||
// }
|
||||
|
||||
// public Stop getStop(String stopName) {
|
||||
// // if (this.name.equals(stopName)) {
|
||||
// // return this;
|
||||
// // }
|
||||
// // for (BifStop b : connected) {
|
||||
// // if (b.stop.name.equals(stopName)) {
|
||||
// // return b.stop;
|
||||
// // }
|
||||
// // }
|
||||
// // return null;
|
||||
// return transport.getStopFromIndex(stopName);
|
||||
// }
|
||||
public boolean isStopConnected(String stopName) {
|
||||
return connected.containsKey(stopName);
|
||||
}
|
||||
|
||||
public void addConnectedStop(BifStop stop) {
|
||||
connected.put(stop.stop.name, stop);
|
||||
}
|
||||
|
||||
public BifStop getConnectedStop(String stopName) {
|
||||
return connected.get(stopName);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
package fr.u_paris.gla.project.idfm;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class TraceDescription {
|
||||
public String from;
|
||||
public String to;
|
||||
public String first;
|
||||
public String last;
|
||||
List<Integer> bifurcation = new ArrayList<>();
|
||||
|
||||
public TraceDescription(String fr,String t, String f, String l){
|
||||
from = fr;
|
||||
to = t;
|
||||
first = f;
|
||||
last = l;
|
||||
}
|
||||
|
||||
@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 String lname;
|
||||
public final String id;
|
||||
public final String type;
|
||||
|
||||
|
||||
|
||||
|
||||
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) {
|
||||
public TraceEntry(String lname,String ident,String t_type) {
|
||||
super();
|
||||
this.lname = lname;
|
||||
this.id = ident;
|
||||
this.type = t_type;
|
||||
}
|
||||
|
||||
// FIXME list of lists are bad practice in direct access...
|
||||
|
@ -46,4 +55,16 @@ public final class TraceEntry {
|
|||
public void addTerminus(String 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);
|
||||
}
|
||||
}
|
||||
|
|
214
src/main/java/fr/u_paris/gla/project/idfm/Transport.java
Normal file
214
src/main/java/fr/u_paris/gla/project/idfm/Transport.java
Normal file
|
@ -0,0 +1,214 @@
|
|||
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;
|
||||
|
||||
|
||||
public class Transport {
|
||||
Map<String, Stop> stopsMap = new HashMap<>();
|
||||
public String name;
|
||||
public String type;
|
||||
List <TraceDescription> descriptions = new ArrayList<>();
|
||||
|
||||
|
||||
public Transport(String n,String t_type){
|
||||
name = n;
|
||||
type = t_type;
|
||||
}
|
||||
|
||||
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, 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);
|
||||
}
|
||||
|
||||
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<>(); // Utiliser un HashSet pour les arrêts déjà visités
|
||||
SimpleEntry<Boolean, List<Integer>> sol = roadToLastOptimized(debut.name, debut.name, fin.name, alreadyVisited, new ArrayList<Integer>());
|
||||
if (sol.getKey()) {
|
||||
found++;
|
||||
d.bifurcation = sol.getValue();
|
||||
}
|
||||
}
|
||||
}
|
||||
// System.out.println("J'en ai trouvé " + found);
|
||||
}
|
||||
|
||||
public boolean isTerminus(String stop){
|
||||
for(TraceDescription t: descriptions){
|
||||
if(stop.equals(t.first) || stop.equals(t.last))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public SimpleEntry<Boolean,List<Integer> > roadToLast(String currentStop,String first, String last, List<String> alreadyVisited, List<Integer> bif){
|
||||
|
||||
if(currentStop.equals(last)){
|
||||
return new SimpleEntry<>(true,bif);
|
||||
}
|
||||
|
||||
//Checker if the current stop is the bad terminus
|
||||
if(isTerminus(currentStop)){
|
||||
return new SimpleEntry<>(false,bif);
|
||||
}
|
||||
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<>(bif);
|
||||
if(b.bifurc!= 0)
|
||||
bifCopy.add(b.bifurc);
|
||||
solutions.add(roadToLast(b.stop.name, first, 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) ;
|
||||
}
|
||||
|
||||
public SimpleEntry<Boolean, List<Integer>> roadToLastOptimized(String currentStop, String first, String last, Set<String> alreadyVisited, List<Integer> bif) {
|
||||
if (currentStop.equals(last)) {
|
||||
return new SimpleEntry<>(true, bif);
|
||||
}
|
||||
|
||||
// Checker if the current stop is the bad terminus
|
||||
if (isTerminus(currentStop)) {
|
||||
return new SimpleEntry<>(false, bif);
|
||||
}
|
||||
|
||||
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<>(bif);
|
||||
if (b.bifurc != 0) {
|
||||
bifCopy.add(b.bifurc);
|
||||
}
|
||||
solutions.add(roadToLastOptimized(b.stop.name, first, 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);
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
// public void addStop(String start,String end,int bifurcation){
|
||||
// Stop start_stop;
|
||||
// Stop end_stop;
|
||||
// if (!stopsMap.containsKey(start)){
|
||||
// start_stop = new Stop(start);
|
||||
// stopsMap.put(start, start_stop);
|
||||
// }else{
|
||||
// start_stop = stopsMap.get(start);
|
||||
// }
|
||||
|
||||
// if (!stopsMap.containsKey(end)){
|
||||
// end_stop = new Stop(end);
|
||||
// stopsMap.put(end, end_stop);
|
||||
// }else{
|
||||
// end_stop = stopsMap.get(end);
|
||||
// }
|
||||
// start_stop.connected.add( new BifStop(bifurcation,end_stop) );
|
||||
|
||||
// }
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @param stopsMap
|
||||
* @param start
|
||||
* @param end
|
||||
* @return true if the start stop has been added before the end stop
|
||||
*/
|
||||
public boolean startBeforeEnd( String start, String end) {
|
||||
for (String key : stopsMap.keySet()) {
|
||||
if (key.equals(start)) {
|
||||
return true;
|
||||
}
|
||||
if (key.equals(end)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// 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) {
|
||||
// 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);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -6,6 +6,7 @@ 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;
|
||||
|
||||
|
@ -68,11 +69,11 @@ public final class CSVTools {
|
|||
* @throws IOException if we can't write the data into the file
|
||||
*/
|
||||
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)) {
|
||||
CSVWriterBuilder wBuilder = new CSVWriterBuilder(writer).withSeparator(';');
|
||||
try (ICSVWriter csv = wBuilder.build()) {
|
||||
contentLineConsumer.forEachOrdered(csv::writeNext);
|
||||
contentLinesConsumer.forEachOrdered(line -> Arrays.stream(line).forEach(csv::writeNext));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Reference in a new issue