Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Review/nav 87 include refactorings from nav 83 review #47

Merged
merged 70 commits into from
Jun 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
70 commits
Select commit Hold shift + click to select a range
d69b3c7
REFACTOR: NAV-35 - Move GtfsRaptor converters to service.gtfsraptor
clukas1 May 27, 2024
13be5eb
ENH: NAV-35 - Basic implementation of transfer generator.
clukas1 May 27, 2024
379e063
REFACTOR: NAV-32 - Split samestation and walk transfer generators in …
connoll1 May 28, 2024
323cfd4
TEST: NAV-35 - Add tests for transfer generators and walk calculator.
connoll1 May 28, 2024
8da357f
ENH: NAV-53 - Text search based on Trie index
munterfi May 30, 2024
ee23c1e
ENH: NAV-53 - Add head sign to GTFS trips
munterfi May 30, 2024
c1c35cb
ENH: NAV-53 - Service implementation
munterfi May 30, 2024
3a6748c
ENH: NAV-53 - Add support for duplicates to search index
munterfi May 30, 2024
ec58ae3
DOC: NAV-53 - Add TODO concerning the memory usage of the search index
munterfi May 30, 2024
dcb75bf
ENH: NAV-53 - Add transfer as third leg type
munterfi May 30, 2024
681d6f5
ENH: NAV-53 - Add spring boot public transit service
munterfi May 30, 2024
f52005e
ENH: NAV-53 - Add direct walk type to the walk
munterfi May 31, 2024
2821bea
FIX: NAV-53 - Ignore order of duplicates in search index
munterfi May 31, 2024
84416e6
ENH: NAV-35 - Remove concurrent linked queue and use stream api
munterfi May 31, 2024
f2736aa
FIX: NAV-35 - Return mutable ArrayList instead of immutable list from…
clukas1 May 31, 2024
782acbb
Merge remote-tracking branch 'origin/feature/NAV-53-build-service-imp…
clukas1 May 31, 2024
b39272d
REFACTOR: NAV-84 - Rename Coordinate DTO to Location.
clukas1 May 31, 2024
44caf28
ENH: NAV-84 - Add lat/lon pair as alternative to stopId to routing re…
clukas1 May 31, 2024
df16c8a
ENH: NAV-84 - Add some validation to controllers and error codes to o…
clukas1 May 31, 2024
458be44
Merge pull request #35 from naviqore/NAV-84-Allow-querying-connection…
munterfi May 31, 2024
3f14a81
ENH: NAV-53 - Add method for connection routing between stops
munterfi May 31, 2024
d0421e3
ENH: NAV-83 - Add Zürich Trams Benchmark GTFS Dataset.
clukas1 May 31, 2024
a289643
ENH: NAV-83 - Add parentStop to GTFS Stop.
clukas1 May 31, 2024
a46fad4
Merge branch 'feature/NAV-35-transfer-generator-for-gtfs-builder' int…
clukas1 May 31, 2024
c338eec
FIX: NAV-83 - Update tests to be compatible with added parent stop id…
clukas1 May 31, 2024
80e21d7
REFACTOR: NAV-81 - Move spatial index from GTFS to service
munterfi Jun 1, 2024
dbd2f79
ENH: NAV-83 - Add ZVV GTFS as test dataset.
clukas1 Jun 1, 2024
8ec86d6
Merge pull request #39 from naviqore/feature/NAV-81-move-kd-tree-to-s…
clukas1 Jun 1, 2024
957615d
Merge branch 'feature/NAV-53-build-service-implementation-based-on-gt…
clukas1 Jun 1, 2024
f062121
ENH: NAV-86 - Use suffix trie for stop name search
munterfi Jun 1, 2024
c877dab
ENH: NAV-86 - Introduce builder and compress suffix tree
munterfi Jun 1, 2024
dac2324
ENH: NAV-83 - Integrate transfer generator to service.
clukas1 Jun 1, 2024
fcbff24
ENH: NAV-86 - Add trie unit test
munterfi Jun 1, 2024
f5222cf
FIX: NAV-83 - Prevent script failing when no parent stop is present.
clukas1 Jun 1, 2024
dfcc17d
ENH: NAV-87 - Create map of parentIds to stops.
clukas1 Jun 1, 2024
cce9182
ENH: NAV-87 - Add only parentstops to search index.
clukas1 Jun 1, 2024
b16180e
REFACTOR: NAV-87 - Make minmumTimeTransfers list final.
clukas1 Jun 1, 2024
dd84ed3
ENH: NAV-87 - Add logic to return closestStops and nextDepartures for…
clukas1 Jun 1, 2024
c8ab9f3
ENH: NAV-87 - Add mutli-stop source and target implementation for rap…
clukas1 Jun 1, 2024
236a5fa
REFACTOR: NAV-87 - Move test to update package structure.
clukas1 Jun 2, 2024
196fd66
ENH: NAV-86 -Add test for suffixes
munterfi Jun 2, 2024
00a2418
ENH: NAV-87 - Add support for handicap times for different target sto…
clukas1 Jun 2, 2024
77263e5
ENH: NAV-86 - Working implementation of compressed trie
munterfi Jun 2, 2024
e6b9e9b
STYLE: NAV-86 - Rename type to searchType in rest controller
munterfi Jun 2, 2024
c3174b8
DOC: NAV-86 - Comment compressed trie
munterfi Jun 2, 2024
c28f701
ENH: NAV-86 - Reduce the memory footprint of trie by trimming the cap…
munterfi Jun 2, 2024
7472961
Merge pull request #42 from naviqore/NAV-86-suffix-trie
munterfi Jun 2, 2024
7f46dca
ENH: NAV-87 - Add parent stop logic to get connections.
clukas1 Jun 2, 2024
49cb58e
ENH: NAV-87 - Implement isolines in service and raptor.
clukas1 Jun 2, 2024
a2c0c1f
Merge branch 'feature/NAV-53-build-service-implementation-based-on-gt…
clukas1 Jun 3, 2024
8c5de45
REFACTOR: NAV-87 - Remove model package for raptor.
clukas1 Jun 3, 2024
952c0b9
REFACTOR: NAV-87 - Introduce ServiceConfig class and Initializer stat…
clukas1 Jun 3, 2024
fca61b7
REFACTOR: NAV-87 - Format GTFS package.
clukas1 Jun 3, 2024
03799e3
REFACTOR: NAV-87 - Move and rename packages.
clukas1 Jun 3, 2024
b482b9e
REFACTOR: NAV-87 - Move Walk record as public subclass to WalkCalcula…
clukas1 Jun 3, 2024
87991d9
REFACTOR: NAV-87 - Update application.properties to hold all required…
clukas1 Jun 3, 2024
7eabfd3
REFACTOR: NAV-87 - Move contants to top of class.
clukas1 Jun 3, 2024
681a73d
REFACTOR: NAV-87 - Move MinimumTimeTransfer record inside TransferGen…
clukas1 Jun 3, 2024
b729df9
REFACTOR: NAV-87 - Hopefully make the transfer generation more readable.
clukas1 Jun 3, 2024
de76c24
REFACTOR: NAV-87 - Use junit setup methods in tests.
clukas1 Jun 3, 2024
0b7877e
ENH: NAV-87 - Implement Isolines in Service.
clukas1 Jun 3, 2024
ea108e3
ENH: NAV-87 - Add support for all connections (stop-coordinate, stop-…
clukas1 Jun 3, 2024
01d1ef2
FIX: NAV-87 - Add stop name instead of id to search index.
clukas1 Jun 4, 2024
fb5fa93
FIX: NAV-83 - Pass correct targetStops array to get earliest arrivals…
clukas1 Jun 4, 2024
16be79b
FIX: NAV-87 - Prevent null pointer exception when trying to build con…
clukas1 Jun 4, 2024
332db38
TEST: NAV-87 - Add test for get isolines from location in service imp…
clukas1 Jun 4, 2024
e735ee0
FIX: NAV-87 - Remove walkTime for Child Stops and Fix last mile walk.
connoll1 Jun 4, 2024
ca035dd
REFACTOR: NAV-87 - Move Hashmap closer to where it's used.
connoll1 Jun 4, 2024
94e1495
Merge branch 'NAV-87-Add-support-to-route-from-parent-stop-to-parent-…
connoll1 Jun 4, 2024
264b267
Merge branch 'main' into review/NAV-87-include-refactorings-fromNAV-8…
connoll1 Jun 4, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 4 additions & 13 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -137,12 +137,12 @@
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>3.0.0-beta2</version>
<version>2.23.1</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>3.0.0-beta2</version>
<version>2.23.1</version>
</dependency>
<!-- io -->
<dependency>
Expand All @@ -155,7 +155,7 @@
<artifactId>commons-csv</artifactId>
<version>1.11.0</version>
</dependency>
<!-- api-->
<!-- spring boot rest app -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
Expand All @@ -165,17 +165,8 @@
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>2.0.1.Final</version>
</dependency>
<dependency>
<groupId>io.swagger.core.v3</groupId>
<artifactId>swagger-annotations</artifactId>
<version>2.2.22</version>
</dependency>
</dependencies>

<repositories>
<repository>
<id>maven_central</id>
Expand Down
116 changes: 108 additions & 8 deletions src/main/java/ch/naviqore/app/controller/RoutingController.java
Original file line number Diff line number Diff line change
@@ -1,39 +1,139 @@
package ch.naviqore.app.controller;

import ch.naviqore.app.model.Connection;
import ch.naviqore.app.model.EarliestArrival;
import ch.naviqore.app.dto.Connection;
import ch.naviqore.app.dto.DtoMapper;
import ch.naviqore.app.dto.EarliestArrival;
import ch.naviqore.service.PublicTransitService;
import ch.naviqore.service.Stop;
import ch.naviqore.service.TimeType;
import ch.naviqore.service.config.ConnectionQueryConfig;
import ch.naviqore.service.exception.StopNotFoundException;
import ch.naviqore.utils.spatial.GeoCoordinate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.server.ResponseStatusException;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import static ch.naviqore.app.dto.DtoMapper.map;

@RestController
@RequestMapping("/routing")
public class RoutingController {

private final PublicTransitService service;

@Autowired
public RoutingController(PublicTransitService service) {
this.service = service;
}

@GetMapping("/connections")
public List<Connection> getConnections(@RequestParam String sourceStopId, @RequestParam String targetStopId,
public List<Connection> getConnections(@RequestParam(required = false) String sourceStopId,
@RequestParam(required = false, defaultValue = "-1.0") double sourceLatitude,
@RequestParam(required = false, defaultValue = "-1.0") double sourceLongitude,
@RequestParam(required = false) String targetStopId,
@RequestParam(required = false, defaultValue = "-1.0") double targetLatitude,
@RequestParam(required = false, defaultValue = "-1.0") double targetLongitude,
@RequestParam(required = false) LocalDateTime departureDateTime,
@RequestParam(required = false, defaultValue = "2147483647") int maxWalkingDuration,
@RequestParam(required = false, defaultValue = "2147483647") int maxTransferNumber,
@RequestParam(required = false, defaultValue = "2147483647") int maxTravelTime,
@RequestParam(required = false, defaultValue = "0") int minTransferTime) {
// TODO: Implement the method with maxWalkingDuration, maxTransferNumber, maxTravelTime, minTransferTime
return DummyData.getConnections(sourceStopId, targetStopId, departureDateTime);
if (sourceStopId == null) {
if (sourceLatitude < 0 || sourceLongitude < 0) {
throw new ResponseStatusException(HttpStatus.BAD_REQUEST,
"Either sourceStopId or sourceLatitude and sourceLongitude must be provided.");
}
}

if (targetStopId == null) {
if (targetLatitude < 0 || targetLongitude < 0) {
throw new ResponseStatusException(HttpStatus.BAD_REQUEST,
"Either targetStopId or targetLatitude and targetLongitude must be provided.");
}
}

if (departureDateTime == null) {
departureDateTime = LocalDateTime.now();
}

Stop sourceStop = sourceStopId != null ? getStop(sourceStopId) : null;
Stop targetStop = targetStopId != null ? getStop(targetStopId) : null;

GeoCoordinate sourceCoordinate = sourceStop == null ? new GeoCoordinate(sourceLatitude, sourceLongitude) : null;
GeoCoordinate targetCoordinate = targetStop == null ? new GeoCoordinate(targetLatitude, targetLongitude) : null;

ConnectionQueryConfig config = new ConnectionQueryConfig(maxWalkingDuration, minTransferTime, maxTransferNumber,
maxTravelTime);

List<ch.naviqore.service.Connection> connections;

if (sourceStop != null && targetStop != null) {
connections = service.getConnections(sourceStop, targetStop, departureDateTime, TimeType.DEPARTURE, config);
} else if (sourceStop != null) {
connections = service.getConnections(sourceStop, targetCoordinate, departureDateTime, TimeType.DEPARTURE,
config);
} else if (targetStop != null) {
connections = service.getConnections(sourceCoordinate, targetStop, departureDateTime, TimeType.DEPARTURE,
config);
} else {
connections = service.getConnections(sourceCoordinate, targetCoordinate, departureDateTime,
TimeType.DEPARTURE, config);
}

return connections.stream().map(DtoMapper::map).toList();
}

@GetMapping("/isolines")
public List<EarliestArrival> getIsolines(@RequestParam String sourceStopId,
public List<EarliestArrival> getIsolines(@RequestParam(required = false) String sourceStopId,
@RequestParam(required = false, defaultValue = "-1.0") double sourceLatitude,
@RequestParam(required = false, defaultValue = "-1.0") double sourceLongitude,
@RequestParam(required = false) LocalDateTime departureDateTime,
@RequestParam(required = false, defaultValue = "2147483647") int maxWalkingDuration,
@RequestParam(required = false, defaultValue = "2147483647") int maxTransferNumber,
@RequestParam(required = false, defaultValue = "2147483647") int maxTravelTime,
@RequestParam(required = false, defaultValue = "0") int minTransferTime) {
// TODO: Implement the method with maxWalkingDuration, maxTransferNumber, minTransferTime
return DummyData.getIsolines(sourceStopId, departureDateTime, maxTravelTime);
if (sourceStopId == null) {
if (sourceLatitude < 0 || sourceLongitude < 0) {
throw new ResponseStatusException(HttpStatus.BAD_REQUEST,
"Either sourceStopId or sourceLatitude and sourceLongitude must be provided.");
}
throw new ResponseStatusException(HttpStatus.NOT_IMPLEMENTED,
"Location based routing is not implemented yet.");
}

Stop sourceStop = getStop(sourceStopId);
ConnectionQueryConfig config = new ConnectionQueryConfig(maxWalkingDuration, minTransferTime, maxTransferNumber,
maxTravelTime);

Map<Stop, ch.naviqore.service.Connection> connections = service.getIsolines(sourceStop, departureDateTime,
config);

List<EarliestArrival> arrivals = new ArrayList<>();

for (Map.Entry<Stop, ch.naviqore.service.Connection> entry : connections.entrySet()) {
Stop stop = entry.getKey();
ch.naviqore.service.Connection connection = entry.getValue();
arrivals.add(map(stop, connection));
}

return arrivals;
}

private ch.naviqore.service.Stop getStop(String stopId) {
try {
return service.getStopById(stopId);
} catch (StopNotFoundException e) {
throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Stop not found", e);
}
}

}
71 changes: 61 additions & 10 deletions src/main/java/ch/naviqore/app/controller/ScheduleController.java
Original file line number Diff line number Diff line change
@@ -1,43 +1,94 @@
package ch.naviqore.app.controller;

import ch.naviqore.app.model.Departure;
import ch.naviqore.app.model.DistanceToStop;
import ch.naviqore.app.model.SearchType;
import ch.naviqore.app.model.Stop;
import ch.naviqore.app.dto.*;
import ch.naviqore.service.ScheduleInformationService;
import ch.naviqore.service.exception.StopNotFoundException;
import ch.naviqore.utils.spatial.GeoCoordinate;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.server.ResponseStatusException;

import java.time.LocalDateTime;
import java.util.List;

import static ch.naviqore.app.dto.DtoMapper.map;

@RestController
@RequestMapping("/schedule")
@Log4j2
public class ScheduleController {

private final ScheduleInformationService service;

@Autowired
public ScheduleController(ScheduleInformationService service) {
this.service = service;
}

private static void validateLimit(int limit) {
if (limit <= 0) {
throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Limit must be greater than 0");
}
}

@GetMapping("/stops/autocomplete")
public List<Stop> getAutoCompleteStops(@RequestParam String query,
@RequestParam(required = false, defaultValue = "10") int limit,
@RequestParam(required = false, defaultValue = "FUZZY") SearchType type) {
return DummyData.searchStops(query, limit, type);
@RequestParam(required = false, defaultValue = "STARTS_WITH") SearchType searchType) {
validateLimit(limit);
return service.getStops(query, map(searchType)).stream().map(DtoMapper::map).limit(limit).toList();
}

@GetMapping("/stops/nearest")
public List<DistanceToStop> getNearestStops(@RequestParam double latitude, @RequestParam double longitude,
@RequestParam(required = false, defaultValue = "1000") int maxDistance,
@RequestParam(required = false, defaultValue = "10") int limit) {
return DummyData.getNearestStops(latitude, longitude, maxDistance, limit);
validateLimit(limit);
if (maxDistance < 0) {
throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Max distance can not be negative");
}

return service.getNearestStops(new GeoCoordinate(latitude, longitude), maxDistance, limit)
.stream()
.map(stop -> map(stop, latitude, longitude))
.toList();
}

@GetMapping("/stops/{stopId}")
public Stop getStop(@PathVariable String stopId) {
return DummyData.getStop(stopId);
try {
return map(service.getStopById(stopId));
} catch (StopNotFoundException e) {
throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Stop not found", e);
}
}

@GetMapping("/stops/{stopId}/departures")
public List<Departure> getDepartures(@PathVariable String stopId,
@RequestParam(required = false) LocalDateTime departureDateTime,
@RequestParam(required = false, defaultValue = "10") int limit,
@RequestParam(required = false) LocalDateTime untilDateTime) {
return DummyData.getDepartures(stopId, departureDateTime, limit, untilDateTime);
}
validateLimit(limit);
if (departureDateTime == null) {
departureDateTime = LocalDateTime.now();
}
if (untilDateTime != null) {
if (untilDateTime.isBefore(departureDateTime)) {
throw new ResponseStatusException(HttpStatus.BAD_REQUEST,
"Until date time must be after departure date time");
}
}

try {
return service.getNextDepartures(service.getStopById(stopId), departureDateTime, untilDateTime, limit)
.stream()
.map(DtoMapper::map)
.toList();
} catch (StopNotFoundException e) {
throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Stop not found", e);
}

}
}
16 changes: 16 additions & 0 deletions src/main/java/ch/naviqore/app/dto/Connection.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package ch.naviqore.app.dto;

import lombok.*;

import java.util.List;

@RequiredArgsConstructor(access = AccessLevel.PACKAGE)
@EqualsAndHashCode
@ToString
@Getter
public class Connection {

private final List<Leg> legs;

}

15 changes: 15 additions & 0 deletions src/main/java/ch/naviqore/app/dto/Departure.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package ch.naviqore.app.dto;

import lombok.*;

@RequiredArgsConstructor(access = AccessLevel.PACKAGE)
@EqualsAndHashCode
@ToString
@Getter
public class Departure {

private final StopTime stopTime;
private final Trip trip;

}

15 changes: 15 additions & 0 deletions src/main/java/ch/naviqore/app/dto/DistanceToStop.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package ch.naviqore.app.dto;

import lombok.*;

@RequiredArgsConstructor(access = AccessLevel.PACKAGE)
@EqualsAndHashCode
@ToString
@Getter
public class DistanceToStop {

private final Stop stop;
private final double distance;

}

Loading