From b39afe0c7d7f226d13c04c9b0c540a758b0d78b8 Mon Sep 17 00:00:00 2001 From: Lukas Connolly Date: Fri, 24 May 2024 07:07:28 +0200 Subject: [PATCH 01/11] ENH: NAV-16 - Add very basic spring service. --- pom.xml | 22 ++++++++++++++++++- .../java/ch/naviqore/api/Application.java | 13 +++++++++++ .../java/ch/naviqore/api/controller/Test.java | 14 ++++++++++++ 3 files changed, 48 insertions(+), 1 deletion(-) create mode 100644 src/main/java/ch/naviqore/api/Application.java create mode 100644 src/main/java/ch/naviqore/api/controller/Test.java diff --git a/pom.xml b/pom.xml index ca94c082..f257e679 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,12 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - + + org.springframework.boot + spring-boot-starter-parent + 3.3.0 + + ch.naviqore naviqore-raptor 1.0.0-SNAPSHOT @@ -42,6 +47,7 @@ UTF-8 + 21 21 21 @@ -72,6 +78,10 @@ + + org.springframework.boot + spring-boot-maven-plugin + @@ -135,6 +145,16 @@ commons-csv 1.10.0 + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-test + test + diff --git a/src/main/java/ch/naviqore/api/Application.java b/src/main/java/ch/naviqore/api/Application.java new file mode 100644 index 00000000..fa4c0a14 --- /dev/null +++ b/src/main/java/ch/naviqore/api/Application.java @@ -0,0 +1,13 @@ +package ch.naviqore.api; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class Application { + + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } + +} diff --git a/src/main/java/ch/naviqore/api/controller/Test.java b/src/main/java/ch/naviqore/api/controller/Test.java new file mode 100644 index 00000000..a4a1c855 --- /dev/null +++ b/src/main/java/ch/naviqore/api/controller/Test.java @@ -0,0 +1,14 @@ +package ch.naviqore.api.controller; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class Test { + + @GetMapping("/test") + public String testEndpoint() { + return "Hello, World!"; + } + +} From dd15424ed121f0a3f6aef22e5cd842be4a4604a0 Mon Sep 17 00:00:00 2001 From: Lukas Connolly Date: Fri, 24 May 2024 12:36:43 +0200 Subject: [PATCH 02/11] ENH: NAV-16 - Add autogenerated models for rest api dto based on openapi.yaml --- pom.xml | 11 + .../api/controller/RoutingController.java | 18 + .../api/controller/ScheduleController.java | 30 ++ .../ch/naviqore/api/model/Autocomplete.java | 99 ++++++ .../ch/naviqore/api/model/Connection.java | 85 +++++ .../java/ch/naviqore/api/model/Isoline.java | 142 ++++++++ .../api/model/IsolineCoordinatesInner.java | 102 ++++++ src/main/java/ch/naviqore/api/model/Leg.java | 194 ++++++++++ .../java/ch/naviqore/api/model/Route.java | 98 ++++++ src/main/java/ch/naviqore/api/model/Stop.java | 182 ++++++++++ .../java/ch/naviqore/api/model/StopTime.java | 145 ++++++++ src/main/resources/api/openapi.yaml | 333 ++++++++++++++++++ 12 files changed, 1439 insertions(+) create mode 100644 src/main/java/ch/naviqore/api/controller/RoutingController.java create mode 100644 src/main/java/ch/naviqore/api/controller/ScheduleController.java create mode 100644 src/main/java/ch/naviqore/api/model/Autocomplete.java create mode 100644 src/main/java/ch/naviqore/api/model/Connection.java create mode 100644 src/main/java/ch/naviqore/api/model/Isoline.java create mode 100644 src/main/java/ch/naviqore/api/model/IsolineCoordinatesInner.java create mode 100644 src/main/java/ch/naviqore/api/model/Leg.java create mode 100644 src/main/java/ch/naviqore/api/model/Route.java create mode 100644 src/main/java/ch/naviqore/api/model/Stop.java create mode 100644 src/main/java/ch/naviqore/api/model/StopTime.java create mode 100644 src/main/resources/api/openapi.yaml diff --git a/pom.xml b/pom.xml index f257e679..82b58b35 100644 --- a/pom.xml +++ b/pom.xml @@ -50,6 +50,7 @@ 21 21 21 + 1.6.8 @@ -155,6 +156,16 @@ spring-boot-starter-test test + + javax.validation + validation-api + 2.0.1.Final + + + io.swagger.core.v3 + swagger-annotations + 2.1.12 + diff --git a/src/main/java/ch/naviqore/api/controller/RoutingController.java b/src/main/java/ch/naviqore/api/controller/RoutingController.java new file mode 100644 index 00000000..bea6e000 --- /dev/null +++ b/src/main/java/ch/naviqore/api/controller/RoutingController.java @@ -0,0 +1,18 @@ +package ch.naviqore.api.controller; + +import ch.naviqore.api.model.Autocomplete; +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 java.util.ArrayList; +import java.util.List; + +@RestController +@RequestMapping("/routing") +public class RoutingController { + + + +} diff --git a/src/main/java/ch/naviqore/api/controller/ScheduleController.java b/src/main/java/ch/naviqore/api/controller/ScheduleController.java new file mode 100644 index 00000000..22bf25cc --- /dev/null +++ b/src/main/java/ch/naviqore/api/controller/ScheduleController.java @@ -0,0 +1,30 @@ +package ch.naviqore.api.controller; + +import ch.naviqore.api.model.Autocomplete; +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 java.util.ArrayList; +import java.util.List; + +@RestController +@RequestMapping("/schedule") +public class ScheduleController { + + @GetMapping("/stops/autocomplete") + public List getInquiries(@RequestParam String query) { + List dtos = new ArrayList<>(); + Autocomplete dto = new Autocomplete(); + dto.setId("1"); + dto.setName("Autocomplete 1"); + dtos.add(dto); + dto = new Autocomplete(); + dto.setId("2"); + dto.setName("Autocomplete 2"); + dtos.add(dto); + return dtos; + } + +} diff --git a/src/main/java/ch/naviqore/api/model/Autocomplete.java b/src/main/java/ch/naviqore/api/model/Autocomplete.java new file mode 100644 index 00000000..4fa505d7 --- /dev/null +++ b/src/main/java/ch/naviqore/api/model/Autocomplete.java @@ -0,0 +1,99 @@ +package ch.naviqore.api.model; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.media.Schema; + +import javax.validation.constraints.*; +import java.util.Objects; + +/** + * Autocomplete + */ + + +public class Autocomplete { + + @JsonProperty("id") + private String id; + + @JsonProperty("name") + private String name; + + public Autocomplete id(String id) { + this.id = id; + return this; + } + + /** + * Get id + * @return id + */ + + @Schema(name = "id", required = false) + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public Autocomplete name(String name) { + this.name = name; + return this; + } + + /** + * Get name + * @return name + */ + + @Schema(name = "name", required = false) + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Autocomplete autocomplete = (Autocomplete) o; + return Objects.equals(this.id, autocomplete.id) && + Objects.equals(this.name, autocomplete.name); + } + + @Override + public int hashCode() { + return Objects.hash(id, name); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class Autocomplete {\n"); + sb.append(" id: ").append(toIndentedString(id)).append("\n"); + sb.append(" name: ").append(toIndentedString(name)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } +} + diff --git a/src/main/java/ch/naviqore/api/model/Connection.java b/src/main/java/ch/naviqore/api/model/Connection.java new file mode 100644 index 00000000..ed52df91 --- /dev/null +++ b/src/main/java/ch/naviqore/api/model/Connection.java @@ -0,0 +1,85 @@ +package ch.naviqore.api.model; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.media.Schema; + +import javax.validation.Valid; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +/** + * Connection + */ + +public class Connection { + + @JsonProperty("legs") + @Valid + private List legs = null; + + public Connection legs(List legs) { + this.legs = legs; + return this; + } + + public Connection addLegsItem(Leg legsItem) { + if (this.legs == null) { + this.legs = new ArrayList<>(); + } + this.legs.add(legsItem); + return this; + } + + /** + * Get legs + * @return legs + */ + @Valid + @Schema(name = "legs", required = false) + public List getLegs() { + return legs; + } + + public void setLegs(List legs) { + this.legs = legs; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Connection connection = (Connection) o; + return Objects.equals(this.legs, connection.legs); + } + + @Override + public int hashCode() { + return Objects.hash(legs); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class Connection {\n"); + sb.append(" legs: ").append(toIndentedString(legs)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } +} + diff --git a/src/main/java/ch/naviqore/api/model/Isoline.java b/src/main/java/ch/naviqore/api/model/Isoline.java new file mode 100644 index 00000000..903e2499 --- /dev/null +++ b/src/main/java/ch/naviqore/api/model/Isoline.java @@ -0,0 +1,142 @@ +package ch.naviqore.api.model; + +import java.net.URI; +import java.util.Objects; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import java.time.OffsetDateTime; +import java.util.ArrayList; +import java.util.List; +import org.springframework.format.annotation.DateTimeFormat; +import java.time.OffsetDateTime; +import javax.validation.Valid; +import javax.validation.constraints.*; +import io.swagger.v3.oas.annotations.media.Schema; + + +import java.util.*; + +/** + * Isoline + */ + +public class Isoline { + + @JsonProperty("stopId") + private String stopId; + + @JsonProperty("departureTime") + @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) + private OffsetDateTime departureTime; + + @JsonProperty("coordinates") + @Valid + private List coordinates = null; + + public Isoline stopId(String stopId) { + this.stopId = stopId; + return this; + } + + /** + * Get stopId + * @return stopId + */ + + @Schema(name = "stopId", required = false) + public String getStopId() { + return stopId; + } + + public void setStopId(String stopId) { + this.stopId = stopId; + } + + public Isoline departureTime(OffsetDateTime departureTime) { + this.departureTime = departureTime; + return this; + } + + /** + * Get departureTime + * @return departureTime + */ + @Valid + @Schema(name = "departureTime", required = false) + public OffsetDateTime getDepartureTime() { + return departureTime; + } + + public void setDepartureTime(OffsetDateTime departureTime) { + this.departureTime = departureTime; + } + + public Isoline coordinates(List coordinates) { + this.coordinates = coordinates; + return this; + } + + public Isoline addCoordinatesItem(IsolineCoordinatesInner coordinatesItem) { + if (this.coordinates == null) { + this.coordinates = new ArrayList<>(); + } + this.coordinates.add(coordinatesItem); + return this; + } + + /** + * Get coordinates + * @return coordinates + */ + @Valid + @Schema(name = "coordinates", required = false) + public List getCoordinates() { + return coordinates; + } + + public void setCoordinates(List coordinates) { + this.coordinates = coordinates; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Isoline isoline = (Isoline) o; + return Objects.equals(this.stopId, isoline.stopId) && + Objects.equals(this.departureTime, isoline.departureTime) && + Objects.equals(this.coordinates, isoline.coordinates); + } + + @Override + public int hashCode() { + return Objects.hash(stopId, departureTime, coordinates); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class Isoline {\n"); + sb.append(" stopId: ").append(toIndentedString(stopId)).append("\n"); + sb.append(" departureTime: ").append(toIndentedString(departureTime)).append("\n"); + sb.append(" coordinates: ").append(toIndentedString(coordinates)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } +} + diff --git a/src/main/java/ch/naviqore/api/model/IsolineCoordinatesInner.java b/src/main/java/ch/naviqore/api/model/IsolineCoordinatesInner.java new file mode 100644 index 00000000..c8f6d90a --- /dev/null +++ b/src/main/java/ch/naviqore/api/model/IsolineCoordinatesInner.java @@ -0,0 +1,102 @@ +package ch.naviqore.api.model; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonTypeName; +import io.swagger.v3.oas.annotations.media.Schema; + +import javax.validation.Valid; +import javax.validation.constraints.*; +import java.math.BigDecimal; +import java.util.Objects; + +/** + * IsolineCoordinatesInner + */ + +@JsonTypeName("Isoline_coordinates_inner") +public class IsolineCoordinatesInner { + + @JsonProperty("latitude") + private BigDecimal latitude; + + @JsonProperty("longitude") + private BigDecimal longitude; + + public IsolineCoordinatesInner latitude(BigDecimal latitude) { + this.latitude = latitude; + return this; + } + + /** + * Get latitude + * @return latitude + */ + @Valid + @Schema(name = "latitude", required = false) + public BigDecimal getLatitude() { + return latitude; + } + + public void setLatitude(BigDecimal latitude) { + this.latitude = latitude; + } + + public IsolineCoordinatesInner longitude(BigDecimal longitude) { + this.longitude = longitude; + return this; + } + + /** + * Get longitude + * @return longitude + */ + @Valid + @Schema(name = "longitude", required = false) + public BigDecimal getLongitude() { + return longitude; + } + + public void setLongitude(BigDecimal longitude) { + this.longitude = longitude; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + IsolineCoordinatesInner isolineCoordinatesInner = (IsolineCoordinatesInner) o; + return Objects.equals(this.latitude, isolineCoordinatesInner.latitude) && + Objects.equals(this.longitude, isolineCoordinatesInner.longitude); + } + + @Override + public int hashCode() { + return Objects.hash(latitude, longitude); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class IsolineCoordinatesInner {\n"); + sb.append(" latitude: ").append(toIndentedString(latitude)).append("\n"); + sb.append(" longitude: ").append(toIndentedString(longitude)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } +} + diff --git a/src/main/java/ch/naviqore/api/model/Leg.java b/src/main/java/ch/naviqore/api/model/Leg.java new file mode 100644 index 00000000..c51fedf1 --- /dev/null +++ b/src/main/java/ch/naviqore/api/model/Leg.java @@ -0,0 +1,194 @@ +package ch.naviqore.api.model; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.media.Schema; + +import javax.validation.constraints.*; +import java.util.Objects; + +/** + * Leg + */ + +public class Leg { + + @JsonProperty("id") + private String id; + + @JsonProperty("fromStopId") + private String fromStopId; + + @JsonProperty("toStopId") + private String toStopId; + + @JsonProperty("departureTime") + private String departureTime; + + @JsonProperty("arrivalTime") + private String arrivalTime; + + @JsonProperty("type") + private String type; + + public Leg id(String id) { + this.id = id; + return this; + } + + /** + * Get id + * @return id + */ + + @Schema(name = "id", required = false) + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public Leg fromStopId(String fromStopId) { + this.fromStopId = fromStopId; + return this; + } + + /** + * Get fromStopId + * @return fromStopId + */ + + @Schema(name = "fromStopId", required = false) + public String getFromStopId() { + return fromStopId; + } + + public void setFromStopId(String fromStopId) { + this.fromStopId = fromStopId; + } + + public Leg toStopId(String toStopId) { + this.toStopId = toStopId; + return this; + } + + /** + * Get toStopId + * @return toStopId + */ + + @Schema(name = "toStopId", required = false) + public String getToStopId() { + return toStopId; + } + + public void setToStopId(String toStopId) { + this.toStopId = toStopId; + } + + public Leg departureTime(String departureTime) { + this.departureTime = departureTime; + return this; + } + + /** + * Get departureTime + * @return departureTime + */ + + @Schema(name = "departureTime", required = false) + public String getDepartureTime() { + return departureTime; + } + + public void setDepartureTime(String departureTime) { + this.departureTime = departureTime; + } + + public Leg arrivalTime(String arrivalTime) { + this.arrivalTime = arrivalTime; + return this; + } + + /** + * Get arrivalTime + * @return arrivalTime + */ + + @Schema(name = "arrivalTime", required = false) + public String getArrivalTime() { + return arrivalTime; + } + + public void setArrivalTime(String arrivalTime) { + this.arrivalTime = arrivalTime; + } + + public Leg type(String type) { + this.type = type; + return this; + } + + /** + * Get type + * @return type + */ + + @Schema(name = "type", required = false) + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Leg leg = (Leg) o; + return Objects.equals(this.id, leg.id) && + Objects.equals(this.fromStopId, leg.fromStopId) && + Objects.equals(this.toStopId, leg.toStopId) && + Objects.equals(this.departureTime, leg.departureTime) && + Objects.equals(this.arrivalTime, leg.arrivalTime) && + Objects.equals(this.type, leg.type); + } + + @Override + public int hashCode() { + return Objects.hash(id, fromStopId, toStopId, departureTime, arrivalTime, type); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class Leg {\n"); + sb.append(" id: ").append(toIndentedString(id)).append("\n"); + sb.append(" fromStopId: ").append(toIndentedString(fromStopId)).append("\n"); + sb.append(" toStopId: ").append(toIndentedString(toStopId)).append("\n"); + sb.append(" departureTime: ").append(toIndentedString(departureTime)).append("\n"); + sb.append(" arrivalTime: ").append(toIndentedString(arrivalTime)).append("\n"); + sb.append(" type: ").append(toIndentedString(type)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } +} + diff --git a/src/main/java/ch/naviqore/api/model/Route.java b/src/main/java/ch/naviqore/api/model/Route.java new file mode 100644 index 00000000..06ae30c8 --- /dev/null +++ b/src/main/java/ch/naviqore/api/model/Route.java @@ -0,0 +1,98 @@ +package ch.naviqore.api.model; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.media.Schema; + +import javax.validation.constraints.*; +import java.util.Objects; + +/** + * Route + */ + +public class Route { + + @JsonProperty("id") + private String id; + + @JsonProperty("name") + private String name; + + public Route id(String id) { + this.id = id; + return this; + } + + /** + * Get id + * @return id + */ + + @Schema(name = "id", required = false) + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public Route name(String name) { + this.name = name; + return this; + } + + /** + * Get name + * @return name + */ + + @Schema(name = "name", required = false) + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Route route = (Route) o; + return Objects.equals(this.id, route.id) && + Objects.equals(this.name, route.name); + } + + @Override + public int hashCode() { + return Objects.hash(id, name); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class Route {\n"); + sb.append(" id: ").append(toIndentedString(id)).append("\n"); + sb.append(" name: ").append(toIndentedString(name)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } +} + diff --git a/src/main/java/ch/naviqore/api/model/Stop.java b/src/main/java/ch/naviqore/api/model/Stop.java new file mode 100644 index 00000000..fd76ac6a --- /dev/null +++ b/src/main/java/ch/naviqore/api/model/Stop.java @@ -0,0 +1,182 @@ +package ch.naviqore.api.model; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.media.Schema; + +import javax.validation.Valid; +import javax.validation.constraints.*; +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +/** + * Stop + */ +public class Stop { + + @JsonProperty("id") + private String id; + + @JsonProperty("name") + private String name; + + @JsonProperty("latitude") + private BigDecimal latitude; + + @JsonProperty("longitude") + private BigDecimal longitude; + + @JsonProperty("routes") + @Valid + private List routes = null; + + public Stop id(String id) { + this.id = id; + return this; + } + + /** + * Get id + * @return id + */ + + @Schema(name = "id", required = false) + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public Stop name(String name) { + this.name = name; + return this; + } + + /** + * Get name + * @return name + */ + + @Schema(name = "name", required = false) + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Stop latitude(BigDecimal latitude) { + this.latitude = latitude; + return this; + } + + /** + * Get latitude + * @return latitude + */ + @Valid + @Schema(name = "latitude", required = false) + public BigDecimal getLatitude() { + return latitude; + } + + public void setLatitude(BigDecimal latitude) { + this.latitude = latitude; + } + + public Stop longitude(BigDecimal longitude) { + this.longitude = longitude; + return this; + } + + /** + * Get longitude + * @return longitude + */ + @Valid + @Schema(name = "longitude", required = false) + public BigDecimal getLongitude() { + return longitude; + } + + public void setLongitude(BigDecimal longitude) { + this.longitude = longitude; + } + + public Stop routes(List routes) { + this.routes = routes; + return this; + } + + public Stop addRoutesItem(Route routesItem) { + if (this.routes == null) { + this.routes = new ArrayList<>(); + } + this.routes.add(routesItem); + return this; + } + + /** + * Get routes + * @return routes + */ + @Valid + @Schema(name = "routes", required = false) + public List getRoutes() { + return routes; + } + + public void setRoutes(List routes) { + this.routes = routes; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Stop stop = (Stop) o; + return Objects.equals(this.id, stop.id) && + Objects.equals(this.name, stop.name) && + Objects.equals(this.latitude, stop.latitude) && + Objects.equals(this.longitude, stop.longitude) && + Objects.equals(this.routes, stop.routes); + } + + @Override + public int hashCode() { + return Objects.hash(id, name, latitude, longitude, routes); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class Stop {\n"); + sb.append(" id: ").append(toIndentedString(id)).append("\n"); + sb.append(" name: ").append(toIndentedString(name)).append("\n"); + sb.append(" latitude: ").append(toIndentedString(latitude)).append("\n"); + sb.append(" longitude: ").append(toIndentedString(longitude)).append("\n"); + sb.append(" routes: ").append(toIndentedString(routes)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } +} + diff --git a/src/main/java/ch/naviqore/api/model/StopTime.java b/src/main/java/ch/naviqore/api/model/StopTime.java new file mode 100644 index 00000000..256321c6 --- /dev/null +++ b/src/main/java/ch/naviqore/api/model/StopTime.java @@ -0,0 +1,145 @@ +package ch.naviqore.api.model; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.media.Schema; + +import java.util.Objects; + +/** + * StopTime + */ + +public class StopTime { + + @JsonProperty("tripId") + private String tripId; + + @JsonProperty("stopId") + private String stopId; + + @JsonProperty("arrivalTime") + private String arrivalTime; + + @JsonProperty("departureTime") + private String departureTime; + + public StopTime tripId(String tripId) { + this.tripId = tripId; + return this; + } + + /** + * Get tripId + * @return tripId + */ + + @Schema(name = "tripId", required = false) + public String getTripId() { + return tripId; + } + + public void setTripId(String tripId) { + this.tripId = tripId; + } + + public StopTime stopId(String stopId) { + this.stopId = stopId; + return this; + } + + /** + * Get stopId + * @return stopId + */ + + @Schema(name = "stopId", required = false) + public String getStopId() { + return stopId; + } + + public void setStopId(String stopId) { + this.stopId = stopId; + } + + public StopTime arrivalTime(String arrivalTime) { + this.arrivalTime = arrivalTime; + return this; + } + + /** + * Get arrivalTime + * @return arrivalTime + */ + + @Schema(name = "arrivalTime", required = false) + public String getArrivalTime() { + return arrivalTime; + } + + public void setArrivalTime(String arrivalTime) { + this.arrivalTime = arrivalTime; + } + + public StopTime departureTime(String departureTime) { + this.departureTime = departureTime; + return this; + } + + /** + * Get departureTime + * @return departureTime + */ + + @Schema(name = "departureTime", required = false) + public String getDepartureTime() { + return departureTime; + } + + public void setDepartureTime(String departureTime) { + this.departureTime = departureTime; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + StopTime stopTime = (StopTime) o; + return Objects.equals(this.tripId, stopTime.tripId) && + Objects.equals(this.stopId, stopTime.stopId) && + Objects.equals(this.arrivalTime, stopTime.arrivalTime) && + Objects.equals(this.departureTime, stopTime.departureTime); + } + + @Override + public int hashCode() { + return Objects.hash(tripId, stopId, arrivalTime, departureTime); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class StopTime {\n"); + sb.append(" tripId: ").append(toIndentedString(tripId)).append("\n"); + sb.append(" stopId: ").append(toIndentedString(stopId)).append("\n"); + sb.append(" arrivalTime: ").append(toIndentedString(arrivalTime)).append("\n"); + sb.append(" departureTime: ").append(toIndentedString(departureTime)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } +} + diff --git a/src/main/resources/api/openapi.yaml b/src/main/resources/api/openapi.yaml new file mode 100644 index 00000000..aa6fb809 --- /dev/null +++ b/src/main/resources/api/openapi.yaml @@ -0,0 +1,333 @@ +openapi: 3.0.0 +info: + title: Naviqore Public Transit API + version: 1.0.0 + description: API for Public Transit Routing System +paths: + /schedule/stops/autocomplete: + get: + summary: Autocomplete station names + description: Provides station names and their corresponding station IDs based on a partial input query. + tags: + - schedule + parameters: + - name: query + in: query + required: true + schema: + type: string + description: Partial name of the station to search for. + responses: + '200': + description: A list of station names and IDs that match the query + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/Autocomplete' + examples: + example: + value: + - id: "1" + name: "Zuerich HB" + - id: "2" + name: "Zuerich Altstetten" + /schedule/stops/{stopId}/departures: + get: + summary: Get next departures from a stop + description: Retrieves the next departures from a specified stop at a given datetime. + tags: + - schedule + parameters: + - name: stopId + in: path + required: true + schema: + type: string + description: The ID of the stop. + - name: dateTime + in: query + required: true + schema: + type: string + format: date-time + description: The date and time for which the next departures are requested. + - name: limit + in: query + required: true + schema: + type: integer + description: The maximum number of departures to return. + responses: + '200': + description: A list of the next departures from the specified stop. + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/StopTime' + examples: + example: + value: + - tripId: "123" + stopId: "1" + arrivalTime: "08:00:00" + departureTime: "08:05:00" + - tripId: "456" + stopId: "1" + arrivalTime: "08:10:00" + departureTime: "08:15:00" + /schedule/stops/nearest: + get: + summary: Get nearest stops + description: Retrieves a list of stops within a specified distance from a given location. + tags: + - schedule + parameters: + - name: latitude + in: query + required: true + schema: + type: number + description: The latitude of the origin location. + - name: longitude + in: query + required: true + schema: + type: number + description: The longitude of the origin location. + - name: maxDistance + in: query + required: true + schema: + type: integer + description: The maximum distance from the origin location to search for stops. + responses: + '200': + description: A list of nearest stops + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/Stop' + examples: + example: + value: + - id: "1" + name: "Zuerich HB" + latitude: 47.378177 + longitude: 8.540192 + - id: "2" + name: "Zuerich Altstetten" + latitude: 47.391555 + longitude: 8.497153 + /schedule/stops/{stopId}: + get: + summary: Get information about a stop + description: Provides detailed information about a specific stop, including coordinates, routes departing from there, and the name. + tags: + - schedule + parameters: + - name: stopId + in: path + required: true + schema: + type: string + description: The ID of the stop. + responses: + '200': + description: Information about the specified stop. + content: + application/json: + schema: + $ref: '#/components/schemas/Stop' + examples: + example: + value: + id: "1" + name: "Zuerich HB" + latitude: 47.378177 + longitude: 8.540192 + routes: + - id: "10" + name: "Tram 10" + - id: "4" + name: "Bus 4" + /routing/connections: + get: + summary: Request connections between two stops + description: Requests connections between two stops at a given departure datetime. + tags: + - routing + parameters: + - name: sourceStopId + in: query + required: true + schema: + type: string + description: The ID of the source stop. + - name: targetStopId + in: query + required: true + schema: + type: string + description: The ID of the target stop. + - name: departureDateTime + in: query + required: true + schema: + type: string + format: date-time + description: The departure datetime from the source stop. + responses: + '200': + description: A list of connections between the specified stops. + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/Connection' + examples: + example: + value: + - legs: + - id: "1" + fromStopId: "1" + toStopId: "2" + departureTime: "08:00:00" + arrivalTime: "08:10:00" + type: "ROUTE" + - id: "2" + fromStopId: "2" + toStopId: "3" + departureTime: "08:15:00" + arrivalTime: "08:25:00" + type: "ROUTE" + /routing/isolines: + get: + summary: Request isolines from a stop + description: Requests isolines from a stop at a given departure datetime. + tags: + - routing + parameters: + - name: stopId + in: query + required: true + schema: + type: string + description: The ID of the stop. + - name: departureDateTime + in: query + required: true + schema: + type: string + format: date-time + description: The departure datetime from the stop. + responses: + '200': + description: A list of isolines from the specified stop. + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/Isoline' + examples: + example: + value: + - stopId: "1" + departureTime: "08:00:00" + coordinates: + - latitude: 47.378177 + longitude: 8.540192 + - latitude: 47.391555 + longitude: 8.497153 +components: + schemas: + Autocomplete: + type: object + properties: + id: + type: string + name: + type: string + StopTime: + type: object + properties: + tripId: + type: string + stopId: + type: string + arrivalTime: + type: string + format: time + departureTime: + type: string + format: time + Stop: + type: object + properties: + id: + type: string + name: + type: string + latitude: + type: number + longitude: + type: number + routes: + type: array + items: + $ref: '#/components/schemas/Route' + Route: + type: object + properties: + id: + type: string + name: + type: string + Connection: + type: object + properties: + legs: + type: array + items: + $ref: '#/components/schemas/Leg' + Leg: + type: object + properties: + id: + type: string + fromStopId: + type: string + toStopId: + type: string + departureTime: + type: string + format: time + arrivalTime: + type: string + format: time + type: + type: string + Isoline: + type: object + properties: + stopId: + type: string + departureTime: + type: string + format: date-time + coordinates: + type: array + items: + type: object + properties: + latitude: + type: number + longitude: + type: number From 35b2850417fd22abcd86377f28db07c2496fde9a Mon Sep 17 00:00:00 2001 From: Lukas Connolly Date: Fri, 24 May 2024 22:00:18 +0200 Subject: [PATCH 03/11] ENH: NAV-16 - Rework openapi.yaml --- pom.xml | 1 - src/main/resources/api/openapi.yaml | 267 +++++++++++++++------------- 2 files changed, 140 insertions(+), 128 deletions(-) diff --git a/pom.xml b/pom.xml index 82b58b35..987de6f2 100644 --- a/pom.xml +++ b/pom.xml @@ -50,7 +50,6 @@ 21 21 21 - 1.6.8 diff --git a/src/main/resources/api/openapi.yaml b/src/main/resources/api/openapi.yaml index aa6fb809..adef953d 100644 --- a/src/main/resources/api/openapi.yaml +++ b/src/main/resources/api/openapi.yaml @@ -17,6 +17,16 @@ paths: schema: type: string description: Partial name of the station to search for. + - name: limit + in: query + schema: + type: integer + description: The maximum number of stations to return. Defaults to `10`. + - name: searchType + in: query + schema: + $ref: '#/components/schemas/SEARCH_TYPE' + description: The type of search to perform. Defaults to `FUZZY`. responses: '200': description: A list of station names and IDs that match the query @@ -25,14 +35,7 @@ paths: schema: type: array items: - $ref: '#/components/schemas/Autocomplete' - examples: - example: - value: - - id: "1" - name: "Zuerich HB" - - id: "2" - name: "Zuerich Altstetten" + $ref: '#/components/schemas/Stop' /schedule/stops/{stopId}/departures: get: summary: Get next departures from a stop @@ -48,17 +51,21 @@ paths: description: The ID of the stop. - name: dateTime in: query - required: true schema: type: string format: date-time - description: The date and time for which the next departures are requested. + description: The date and time for which the next departures are requested. Defaults to the current time. - name: limit in: query - required: true schema: type: integer - description: The maximum number of departures to return. + description: The maximum number of departures to return. Defaults to `10`. + - name: untilDateTime + in: query + schema: + type: string + format: date-time + description: The date and time until which the departures are requested. Defaults to `null` (no limit). responses: '200': description: A list of the next departures from the specified stop. @@ -67,18 +74,7 @@ paths: schema: type: array items: - $ref: '#/components/schemas/StopTime' - examples: - example: - value: - - tripId: "123" - stopId: "1" - arrivalTime: "08:00:00" - departureTime: "08:05:00" - - tripId: "456" - stopId: "1" - arrivalTime: "08:10:00" - departureTime: "08:15:00" + $ref: '#/components/schemas/Departure' /schedule/stops/nearest: get: summary: Get nearest stops @@ -100,10 +96,9 @@ paths: description: The longitude of the origin location. - name: maxDistance in: query - required: true schema: type: integer - description: The maximum distance from the origin location to search for stops. + description: The maximum distance from the origin location to search for stops in meters. Defaults to `1000`. responses: '200': description: A list of nearest stops @@ -112,22 +107,11 @@ paths: schema: type: array items: - $ref: '#/components/schemas/Stop' - examples: - example: - value: - - id: "1" - name: "Zuerich HB" - latitude: 47.378177 - longitude: 8.540192 - - id: "2" - name: "Zuerich Altstetten" - latitude: 47.391555 - longitude: 8.497153 + $ref: '#/components/schemas/DistanceToStop' /schedule/stops/{stopId}: get: summary: Get information about a stop - description: Provides detailed information about a specific stop, including coordinates, routes departing from there, and the name. + description: Provides detailed information about a specific stop, including coordinates and the name. tags: - schedule parameters: @@ -144,18 +128,6 @@ paths: application/json: schema: $ref: '#/components/schemas/Stop' - examples: - example: - value: - id: "1" - name: "Zuerich HB" - latitude: 47.378177 - longitude: 8.540192 - routes: - - id: "10" - name: "Tram 10" - - id: "4" - name: "Bus 4" /routing/connections: get: summary: Request connections between two stops @@ -177,11 +149,30 @@ paths: description: The ID of the target stop. - name: departureDateTime in: query - required: true schema: type: string format: date-time - description: The departure datetime from the source stop. + description: The departure datetime from the source stop. Defaults to the current time. + - name: maxWalkingDuration + in: query + schema: + type: integer + description: The maximum walking duration in seconds. Defaults to `INFINITY`. + - name: maxTransferNumber + in: query + schema: + type: integer + description: The maximum number of transfers between trips allowed in a connection. Defaults to `INFINITY`. + - name: maxTravelTime + in: query + schema: + type: integer + description: The maximum travel time in seconds. Defaults to `INFINITY`. + - name: minTransferTime + in: query + schema: + type: integer + description: The minimum transfer time between trips in seconds. Defaults to `0`. responses: '200': description: A list of connections between the specified stops. @@ -191,26 +182,10 @@ paths: type: array items: $ref: '#/components/schemas/Connection' - examples: - example: - value: - - legs: - - id: "1" - fromStopId: "1" - toStopId: "2" - departureTime: "08:00:00" - arrivalTime: "08:10:00" - type: "ROUTE" - - id: "2" - fromStopId: "2" - toStopId: "3" - departureTime: "08:15:00" - arrivalTime: "08:25:00" - type: "ROUTE" /routing/isolines: get: - summary: Request isolines from a stop - description: Requests isolines from a stop at a given departure datetime. + summary: Request a list of fastest connections to each reachable stop + description: Request a list of fastest connections to each reachable stop from a specified stop at a given departure datetime. tags: - routing parameters: @@ -222,52 +197,52 @@ paths: description: The ID of the stop. - name: departureDateTime in: query - required: true schema: type: string format: date-time - description: The departure datetime from the stop. + description: The departure datetime from the stop. Defaults to the current time. + - name: maxWalkingDuration + in: query + schema: + type: integer + description: The maximum walking duration in seconds. Defaults to `INFINITY`. + - name: maxTransferNumber + in: query + schema: + type: integer + description: The maximum number of transfers between trips allowed in a connection. Defaults to `INFINITY`. + - name: maxTravelTime + in: query + schema: + type: integer + description: The maximum travel time in seconds. Defaults to `INFINITY`. + - name: minTransferTime + in: query + schema: + type: integer + description: The minimum transfer time between trips in seconds. Defaults to `0`. responses: '200': - description: A list of isolines from the specified stop. + description: A list of stop and fastest connection pairs for each reachable stop. content: application/json: schema: type: array items: - $ref: '#/components/schemas/Isoline' - examples: - example: - value: - - stopId: "1" - departureTime: "08:00:00" - coordinates: - - latitude: 47.378177 - longitude: 8.540192 - - latitude: 47.391555 - longitude: 8.497153 + $ref: '#/components/schemas/EarliestArrival' components: schemas: - Autocomplete: - type: object - properties: - id: - type: string - name: - type: string StopTime: type: object properties: - tripId: - type: string - stopId: - type: string + stop: + $ref: '#/components/schemas/Stop' arrivalTime: type: string - format: time + format: date-time departureTime: type: string - format: time + format: date-time Stop: type: object properties: @@ -275,14 +250,8 @@ components: type: string name: type: string - latitude: - type: number - longitude: - type: number - routes: - type: array - items: - $ref: '#/components/schemas/Route' + coordinates: + $ref: '#/components/schemas/Coordinate' Route: type: object properties: @@ -290,6 +259,10 @@ components: type: string name: type: string + shortName: + type: string + transportMode: + type: string Connection: type: object properties: @@ -300,34 +273,74 @@ components: Leg: type: object properties: - id: - type: string - fromStopId: - type: string - toStopId: - type: string + from: + $ref: '#/components/schemas/Coordinate' + to: + $ref: '#/components/schemas/Coordinate' + fromStop: + $ref: '#/components/schemas/Stop' + toStop: + $ref: '#/components/schemas/Stop' + type: + $ref: '#/components/schemas/LegType' departureTime: type: string - format: time + format: date-time arrivalTime: type: string - format: time - type: - type: string - Isoline: + format: date-time + EarliestArrival: type: object properties: - stopId: - type: string - departureTime: + stop: + $ref: '#/components/schemas/Stop' + arrivalTime: type: string format: date-time - coordinates: + connection: + $ref: '#/components/schemas/Connection' + Coordinate: + type: object + properties: + latitude: + type: number + longitude: + type: number + Trip: + type: object + properties: + headSign: + type: string + route: + $ref: '#/components/schemas/Route' + stopTimes: type: array items: - type: object - properties: - latitude: - type: number - longitude: - type: number + $ref: '#/components/schemas/StopTime' + Departure: + type: object + properties: + stopTime: + $ref: '#/components/schemas/StopTime' + trip: + $ref: '#/components/schemas/Trip' + LegType: + type: string + enum: + - WALK + - ROUTE + DistanceToStop: + type: object + properties: + stop: + $ref: '#/components/schemas/Stop' + distance: + type: number + SEARCH_TYPE: + type: string + enum: + - EXACT + - STARTS_WITH + - CONTAINS + - ENDS_WITH + - FUZZY From 9ca7f76fc5f92d496459fe061d4878fe0fb77efa Mon Sep 17 00:00:00 2001 From: Lukas Connolly Date: Sat, 25 May 2024 02:50:24 +0200 Subject: [PATCH 04/11] ENH: NAV-16 - Implement all REST API endpoints according to openapi.yaml with Dummy Data. --- .../ch/naviqore/api/controller/DummyData.java | 335 ++++++++++++++++++ .../api/controller/RoutingController.java | 27 +- .../api/controller/ScheduleController.java | 47 ++- .../ch/naviqore/api/model/Autocomplete.java | 99 ------ .../ch/naviqore/api/model/Connection.java | 99 ++---- .../ch/naviqore/api/model/Coordinate.java | 63 ++++ .../java/ch/naviqore/api/model/Departure.java | 62 ++++ .../ch/naviqore/api/model/DistanceToStop.java | 62 ++++ .../naviqore/api/model/EarliestArrival.java | 71 ++++ .../java/ch/naviqore/api/model/Isoline.java | 142 -------- .../api/model/IsolineCoordinatesInner.java | 102 ------ src/main/java/ch/naviqore/api/model/Leg.java | 261 +++++--------- .../java/ch/naviqore/api/model/LegType.java | 42 +++ .../java/ch/naviqore/api/model/Route.java | 124 +++---- .../ch/naviqore/api/model/SearchType.java | 48 +++ src/main/java/ch/naviqore/api/model/Stop.java | 205 +++-------- .../java/ch/naviqore/api/model/StopTime.java | 176 +++------ src/main/java/ch/naviqore/api/model/Trip.java | 69 ++++ src/main/resources/api/openapi.yaml | 2 + 19 files changed, 1077 insertions(+), 959 deletions(-) create mode 100644 src/main/java/ch/naviqore/api/controller/DummyData.java delete mode 100644 src/main/java/ch/naviqore/api/model/Autocomplete.java create mode 100644 src/main/java/ch/naviqore/api/model/Coordinate.java create mode 100644 src/main/java/ch/naviqore/api/model/Departure.java create mode 100644 src/main/java/ch/naviqore/api/model/DistanceToStop.java create mode 100644 src/main/java/ch/naviqore/api/model/EarliestArrival.java delete mode 100644 src/main/java/ch/naviqore/api/model/Isoline.java delete mode 100644 src/main/java/ch/naviqore/api/model/IsolineCoordinatesInner.java create mode 100644 src/main/java/ch/naviqore/api/model/LegType.java create mode 100644 src/main/java/ch/naviqore/api/model/SearchType.java create mode 100644 src/main/java/ch/naviqore/api/model/Trip.java diff --git a/src/main/java/ch/naviqore/api/controller/DummyData.java b/src/main/java/ch/naviqore/api/controller/DummyData.java new file mode 100644 index 00000000..e8152d8e --- /dev/null +++ b/src/main/java/ch/naviqore/api/controller/DummyData.java @@ -0,0 +1,335 @@ +package ch.naviqore.api.controller; + +import ch.naviqore.api.model.*; + +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; + +public class DummyData { + + public static List getStops() { + List dtos = new ArrayList<>(); + dtos.add(new Stop("Stop-1", "Train Station", new Coordinate(47.9, 8.0))); + dtos.add(new Stop("Stop-2", "Bus Station", new Coordinate(47.95, 8.05))); + dtos.add(new Stop("Stop-3", "Tram Station", new Coordinate(48.0, 8.1))); + dtos.add(new Stop("Stop-4", "Central Station", new Coordinate(48.1, 8.0))); + dtos.add(new Stop("Stop-5", "East Station", new Coordinate(47.9, 7.95))); + dtos.add(new Stop("Stop-6", "West Station", new Coordinate(48.15, 8.1))); + dtos.add(new Stop("Stop-7", "North Station", new Coordinate(48.05, 7.9))); + dtos.add(new Stop("Stop-8", "South Station", new Coordinate(48.2, 8.05))); + dtos.add(new Stop("Stop-9", "City Center", new Coordinate(47.95, 8.1))); + dtos.add(new Stop("Stop-10", "Main Square", new Coordinate(48.0, 8.05))); + dtos.add(new Stop("Stop-11", "University", new Coordinate(48.1, 7.95))); + dtos.add(new Stop("Stop-12", "Airport", new Coordinate(47.9, 8.1))); + dtos.add(new Stop("Stop-13", "Harbor", new Coordinate(48.2, 7.9))); + dtos.add(new Stop("Stop-14", "Market Place", new Coordinate(48.05, 8.0))); + dtos.add(new Stop("Stop-15", "Old Town", new Coordinate(47.95, 7.9))); + dtos.add(new Stop("Stop-16", "Industrial Park", new Coordinate(48.0, 8.1))); + dtos.add(new Stop("Stop-17", "Business District", new Coordinate(48.1, 8.05))); + dtos.add(new Stop("Stop-18", "Residential Area", new Coordinate(48.2, 8.0))); + dtos.add(new Stop("Stop-19", "Historic Site", new Coordinate(48.0, 7.95))); + dtos.add(new Stop("Stop-20", "Tech Park", new Coordinate(47.9, 8.05))); + dtos.add(new Stop("Stop-21", "City Hall", new Coordinate(48.1, 7.9))); + dtos.add(new Stop("Stop-22", "Library", new Coordinate(48.2, 8.1))); + dtos.add(new Stop("Stop-23", "Museum", new Coordinate(47.95, 8.0))); + dtos.add(new Stop("Stop-24", "Stadium", new Coordinate(48.05, 8.1))); + dtos.add(new Stop("Stop-25", "Aquarium", new Coordinate(48.0, 8.0))); + dtos.add(new Stop("Stop-26", "Zoo", new Coordinate(48.1, 8.05))); + dtos.add(new Stop("Stop-27", "Botanical Garden", new Coordinate(48.2, 7.95))); + dtos.add(new Stop("Stop-28", "Concert Hall", new Coordinate(48.05, 7.9))); + dtos.add(new Stop("Stop-29", "Exhibition Center", new Coordinate(48.0, 8.1))); + dtos.add(new Stop("Stop-30", "Convention Center", new Coordinate(47.9, 8.0))); + return dtos; + } + + public static List getRoutes() { + List dtos = new ArrayList<>(); + dtos.add(new Route("Route-1", "Train Route 1", "TR-1", "Train")); + dtos.add(new Route("Route-2", "Bus Route 1", "B1", "Bus")); + dtos.add(new Route("Route-3", "Tram Route 1", "T1", "Tram")); + dtos.add(new Route("Route-4", "Train Route 2", "TR-2", "Train")); + return dtos; + } + + public static List searchStops(String query, int limit, SearchType type) { + List stops = getStops(); + List result = new ArrayList<>(); + if (type == SearchType.FUZZY || type == SearchType.CONTAINS) { + for (Stop stop : stops) { + if (stop.getName().toLowerCase().contains(query.toLowerCase())) { + result.add(stop); + } + } + } else if (type == SearchType.STARTS_WITH) { + for (Stop stop : stops) { + if (stop.getName().toLowerCase().startsWith(query.toLowerCase())) { + result.add(stop); + } + } + } else if (type == SearchType.EXACT) { + for (Stop stop : stops) { + if (stop.getName().toLowerCase().endsWith(query.toLowerCase())) { + result.add(stop); + } + } + } else { + for (Stop stop : stops) { + if (stop.getName().equalsIgnoreCase(query)) { + result.add(stop); + } + } + } + if (result.size() > limit) { + return result.subList(0, limit); + } + return result; + } + + public static List getNearestStops(double latitude, double longitude, int maxDistance, int limit) { + List stops = getStops(); + List result = new ArrayList<>(); + for (Stop stop : stops) { + double distance = approximateDistance(stop.getCoordinates(), new Coordinate(latitude, longitude)); + if (maxDistance > 0 && distance > maxDistance) { + continue; + } + result.add(new DistanceToStop(stop, distance)); + } + result.sort(Comparator.comparingDouble(DistanceToStop::getDistance)); + if (result.size() > limit) { + return result.subList(0, limit); + } + return result; + } + + public static double approximateDistance(Coordinate coord1, Coordinate coord2) { + final double metersPerDegreeLat = 111320.0; + final double lat1 = coord1.getLatitude(); + final double lon1 = coord1.getLongitude(); + final double lat2 = coord2.getLatitude(); + final double lon2 = coord2.getLongitude(); + + // Convert latitude and longitude differences to meters + double latDiff = (lat2 - lat1) * metersPerDegreeLat; + double lonDiff = (lon2 - lon1) * metersPerDegreeLat * Math.cos(Math.toRadians((lat1 + lat2) / 2.0)); + + // Use Pythagorean theorem to approximate distance + return Math.sqrt(latDiff * latDiff + lonDiff * lonDiff); + } + + public static Stop getStop(String stopId) { + List stops = getStops(); + for (Stop stop : stops) { + if (stop.getId().equals(stopId)) { + return stop; + } + } + return null; + } + + private static Connection buildSimpleDummyConnection(Stop from, Stop to, LocalDateTime departureTime) { + ArrayList legs = new ArrayList<>(); + legs.add(buildTripDummyLeg(from, to, departureTime)); + + return new Connection(legs); + } + + private static Connection buildTwoLegDummyConnection(Stop from, Stop to, LocalDateTime departureTime) { + + Stop stopBetween = getStopInBetweenStops(from, to); + + if (stopBetween == null) { + return buildSimpleDummyConnection(from, to, departureTime); + } + + ArrayList legs = new ArrayList<>(); + Leg leg1 = buildTripDummyLeg(from, stopBetween, departureTime); + legs.add(leg1); + legs.add(buildTripDummyLeg(stopBetween, to, leg1.getArrivalTime())); + + return new Connection(legs); + } + + private static Connection buildThreeLegDummyConnectionWithFootpath(Stop from, Stop to, + LocalDateTime departureTime) { + + Stop stopBetween = getStopInBetweenStops(from, to); + + if (stopBetween == null) { + return buildTwoLegDummyConnection(from, to, departureTime); + } + + List closestStops = getNearestStops(stopBetween.getCoordinates().getLatitude(), + stopBetween.getCoordinates().getLongitude(), 5000, 10); + + Stop closestStop = null; + + for (DistanceToStop distanceToStop : closestStops) { + if (distanceToStop.getStop().equals(from) || distanceToStop.getStop().equals(to) || distanceToStop.getStop() + .equals(stopBetween)) { + continue; + } + closestStop = distanceToStop.getStop(); + break; + } + + if (closestStop == null) { + return buildTwoLegDummyConnection(from, to, departureTime); + } + + ArrayList legs = new ArrayList<>(); + Leg leg1 = buildTripDummyLeg(from, stopBetween, departureTime); + legs.add(leg1); + + int footpathDistance = (int) approximateDistance(stopBetween.getCoordinates(), closestStop.getCoordinates()); + int footpathSpeed = 100; // meters per minute + int footpathTravelTime = footpathDistance / footpathSpeed; // in minutes + + Leg leg2 = new Leg(stopBetween.getCoordinates(), closestStop.getCoordinates(), stopBetween, closestStop, + LegType.WALK, leg1.getArrivalTime(), leg1.getArrivalTime().plusMinutes(footpathTravelTime), null); + legs.add(leg2); + legs.add(buildTripDummyLeg(closestStop, to, leg2.getArrivalTime())); + + return new Connection(legs); + } + + private static Stop getStopInBetweenStops(Stop from, Stop to) { + List stops = getStops(); + // get all stops between from and to + List stopsBetween = new ArrayList<>(); + for (Stop stop : stops) { + if (stop.equals(from) || stop.equals(to)) { + continue; + } + double maxLat = Math.max(from.getCoordinates().getLatitude(), to.getCoordinates().getLatitude()); + double minLat = Math.min(from.getCoordinates().getLatitude(), to.getCoordinates().getLatitude()); + double maxLon = Math.max(from.getCoordinates().getLongitude(), to.getCoordinates().getLongitude()); + double minLon = Math.min(from.getCoordinates().getLongitude(), to.getCoordinates().getLongitude()); + if (stop.getCoordinates().getLatitude() > minLat && stop.getCoordinates() + .getLatitude() < maxLat && stop.getCoordinates().getLongitude() > minLon && stop.getCoordinates() + .getLongitude() < maxLon) { + stopsBetween.add(stop); + System.out.println("Stop between: " + stop.getName()); + } + } + + if (stopsBetween.isEmpty()) { + return null; + //return stops.get((int) (Math.random() * stops.size())); + } + + return stopsBetween.get((int) (Math.random() * stopsBetween.size())); + } + + private static Leg buildTripDummyLeg(Stop from, Stop to, LocalDateTime departureTime) { + double distance = approximateDistance(from.getCoordinates(), to.getCoordinates()); + // get route randomly + List routes = getRoutes(); + Route route = routes.get((int) (Math.random() * routes.size())); + int speed = 1000; // meters per minute + if (route.getTransportMode().equals("Train")) { + speed = 2000; + } + int travelTime = (int) (distance / speed); // in minutes + LocalDateTime tripDepartureTime = departureTime.plusMinutes((int) (Math.random() * 20)); + LocalDateTime tripArrivalTime = tripDepartureTime.plusMinutes(travelTime); + + ArrayList stopTimes = new ArrayList<>(); + stopTimes.add(new StopTime(from, departureTime, tripDepartureTime)); + stopTimes.add(new StopTime(to, tripArrivalTime, tripArrivalTime)); + + Trip trip = new Trip(to.getName(), route, stopTimes); + + return new Leg(from.getCoordinates(), to.getCoordinates(), from, to, LegType.ROUTE, departureTime, + tripArrivalTime, trip); + } + + public static List getDepartures(String stopId, LocalDateTime departureTime, int limit, + LocalDateTime untilDateTime) { + + Stop stop = getStop(stopId); + + if (departureTime == null) { + departureTime = LocalDateTime.now(); + } + + List departures = new ArrayList<>(); + List stops = getStops(); + + for (Stop targetStop : stops) { + if (stop == targetStop) { + continue; + } + + int randomMinutes = (int) (Math.random() * 120); + LocalDateTime tripDepartureTime = departureTime.plusMinutes(randomMinutes); + Leg leg = buildTripDummyLeg(stop, targetStop, tripDepartureTime); + Trip trip = leg.getTrip(); + + if (untilDateTime != null && leg.getArrivalTime().isAfter(untilDateTime)) { + continue; + } + + departures.add(new Departure(trip.getStopTimes().getFirst(), trip)); + } + + // sort by departure time + departures.sort(Comparator.comparing(departure -> departure.getStopTime().getDepartureTime())); + + if (departures.size() > limit) { + return departures.subList(0, limit); + } + + return departures; + } + + public static List getConnections(String fromStopId, String toStopId, LocalDateTime departureTime) { + Stop from = getStop(fromStopId); + Stop to = getStop(toStopId); + + if (departureTime == null) { + departureTime = LocalDateTime.now(); + } + + List connections = new ArrayList<>(); + connections.add(buildSimpleDummyConnection(from, to, departureTime)); + connections.add(buildTwoLegDummyConnection(from, to, departureTime)); + connections.add(buildThreeLegDummyConnectionWithFootpath(from, to, departureTime)); + + return connections; + } + + public static List getIsolines(String fromStopId, LocalDateTime departureTime, int maxTravelTime) { + Stop from = getStop(fromStopId); + if (departureTime == null) { + departureTime = LocalDateTime.now(); + } + + LocalDateTime untilDateTime = null; + if (maxTravelTime < Integer.MAX_VALUE) { + untilDateTime = departureTime.plusMinutes(maxTravelTime); + } + + List stops = getStops(); + List isolines = new ArrayList<>(); + + for (Stop targetStop : stops) { + if (from == targetStop) { + continue; + } + Connection connection = buildSimpleDummyConnection(from, targetStop, departureTime); + + Leg lastLeg = connection.getLegs().get(connection.getLegs().size() - 1); + if (untilDateTime != null && lastLeg.getArrivalTime().isAfter(untilDateTime)) { + continue; + } + + isolines.add(new EarliestArrival(targetStop, lastLeg.getArrivalTime(), connection)); + } + + return isolines; + } + +} diff --git a/src/main/java/ch/naviqore/api/controller/RoutingController.java b/src/main/java/ch/naviqore/api/controller/RoutingController.java index bea6e000..9a721dfc 100644 --- a/src/main/java/ch/naviqore/api/controller/RoutingController.java +++ b/src/main/java/ch/naviqore/api/controller/RoutingController.java @@ -1,18 +1,39 @@ package ch.naviqore.api.controller; -import ch.naviqore.api.model.Autocomplete; +import ch.naviqore.api.model.Connection; +import ch.naviqore.api.model.EarliestArrival; 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 java.util.ArrayList; +import java.time.LocalDateTime; import java.util.List; @RestController @RequestMapping("/routing") public class RoutingController { - + @GetMapping("/connections") + public List getConnections(@RequestParam String sourceStopId, @RequestParam String targetStopId, + @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); + } + + @GetMapping("/isolines") + public List getIsolines(@RequestParam String sourceStopId, + @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); + } } diff --git a/src/main/java/ch/naviqore/api/controller/ScheduleController.java b/src/main/java/ch/naviqore/api/controller/ScheduleController.java index 22bf25cc..80ab7318 100644 --- a/src/main/java/ch/naviqore/api/controller/ScheduleController.java +++ b/src/main/java/ch/naviqore/api/controller/ScheduleController.java @@ -1,12 +1,12 @@ package ch.naviqore.api.controller; -import ch.naviqore.api.model.Autocomplete; -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 ch.naviqore.api.model.Departure; +import ch.naviqore.api.model.DistanceToStop; +import ch.naviqore.api.model.SearchType; +import ch.naviqore.api.model.Stop; +import org.springframework.web.bind.annotation.*; -import java.util.ArrayList; +import java.time.LocalDateTime; import java.util.List; @RestController @@ -14,17 +14,30 @@ public class ScheduleController { @GetMapping("/stops/autocomplete") - public List getInquiries(@RequestParam String query) { - List dtos = new ArrayList<>(); - Autocomplete dto = new Autocomplete(); - dto.setId("1"); - dto.setName("Autocomplete 1"); - dtos.add(dto); - dto = new Autocomplete(); - dto.setId("2"); - dto.setName("Autocomplete 2"); - dtos.add(dto); - return dtos; + public List getAutoCompleteStops(@RequestParam String query, + @RequestParam(required = false, defaultValue = "10") int limit, + @RequestParam(required = false, defaultValue = "FUZZY") SearchType type) { + return DummyData.searchStops(query, limit, type); + } + + @GetMapping("/stops/nearest") + public List 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); + } + + @GetMapping("/stops/{stopId}") + public Stop getStop(@PathVariable String stopId) { + return DummyData.getStop(stopId); + } + + @GetMapping("/stops/{stopId}/departures") + public List getDepartures(@PathVariable String stopId, + @RequestParam(required = false) LocalDateTime departureTime, + @RequestParam(required = false, defaultValue = "10") int limit, + @RequestParam(required = false) LocalDateTime untilDateTime) { + return DummyData.getDepartures(stopId, departureTime, limit, untilDateTime); } } diff --git a/src/main/java/ch/naviqore/api/model/Autocomplete.java b/src/main/java/ch/naviqore/api/model/Autocomplete.java deleted file mode 100644 index 4fa505d7..00000000 --- a/src/main/java/ch/naviqore/api/model/Autocomplete.java +++ /dev/null @@ -1,99 +0,0 @@ -package ch.naviqore.api.model; - -import com.fasterxml.jackson.annotation.JsonProperty; -import io.swagger.v3.oas.annotations.media.Schema; - -import javax.validation.constraints.*; -import java.util.Objects; - -/** - * Autocomplete - */ - - -public class Autocomplete { - - @JsonProperty("id") - private String id; - - @JsonProperty("name") - private String name; - - public Autocomplete id(String id) { - this.id = id; - return this; - } - - /** - * Get id - * @return id - */ - - @Schema(name = "id", required = false) - public String getId() { - return id; - } - - public void setId(String id) { - this.id = id; - } - - public Autocomplete name(String name) { - this.name = name; - return this; - } - - /** - * Get name - * @return name - */ - - @Schema(name = "name", required = false) - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - Autocomplete autocomplete = (Autocomplete) o; - return Objects.equals(this.id, autocomplete.id) && - Objects.equals(this.name, autocomplete.name); - } - - @Override - public int hashCode() { - return Objects.hash(id, name); - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("class Autocomplete {\n"); - sb.append(" id: ").append(toIndentedString(id)).append("\n"); - sb.append(" name: ").append(toIndentedString(name)).append("\n"); - sb.append("}"); - return sb.toString(); - } - - /** - * Convert the given object to string with each line indented by 4 spaces - * (except the first line). - */ - private String toIndentedString(Object o) { - if (o == null) { - return "null"; - } - return o.toString().replace("\n", "\n "); - } -} - diff --git a/src/main/java/ch/naviqore/api/model/Connection.java b/src/main/java/ch/naviqore/api/model/Connection.java index ed52df91..cc452129 100644 --- a/src/main/java/ch/naviqore/api/model/Connection.java +++ b/src/main/java/ch/naviqore/api/model/Connection.java @@ -1,85 +1,58 @@ package ch.naviqore.api.model; import com.fasterxml.jackson.annotation.JsonProperty; -import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Getter; -import javax.validation.Valid; -import java.util.ArrayList; import java.util.List; import java.util.Objects; /** * Connection */ - +@Getter public class Connection { - @JsonProperty("legs") - @Valid - private List legs = null; - - public Connection legs(List legs) { - this.legs = legs; - return this; - } + @JsonProperty("legs") + private List legs; - public Connection addLegsItem(Leg legsItem) { - if (this.legs == null) { - this.legs = new ArrayList<>(); + public Connection(List legs) { + this.legs = legs; } - this.legs.add(legsItem); - return this; - } - - /** - * Get legs - * @return legs - */ - @Valid - @Schema(name = "legs", required = false) - public List getLegs() { - return legs; - } - - public void setLegs(List legs) { - this.legs = legs; - } - @Override - public boolean equals(Object o) { - if (this == o) { - return true; + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Connection connection = (Connection) o; + return Objects.equals(this.legs, connection.legs); } - if (o == null || getClass() != o.getClass()) { - return false; - } - Connection connection = (Connection) o; - return Objects.equals(this.legs, connection.legs); - } - @Override - public int hashCode() { - return Objects.hash(legs); - } + @Override + public int hashCode() { + return Objects.hash(legs); + } - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("class Connection {\n"); - sb.append(" legs: ").append(toIndentedString(legs)).append("\n"); - sb.append("}"); - return sb.toString(); - } + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class Connection {\n"); + sb.append(" legs: ").append(toIndentedString(legs)).append("\n"); + sb.append("}"); + return sb.toString(); + } - /** - * Convert the given object to string with each line indented by 4 spaces - * (except the first line). - */ - private String toIndentedString(Object o) { - if (o == null) { - return "null"; + /** + * Convert the given object to string with each line indented by 4 spaces (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); } - return o.toString().replace("\n", "\n "); - } } diff --git a/src/main/java/ch/naviqore/api/model/Coordinate.java b/src/main/java/ch/naviqore/api/model/Coordinate.java new file mode 100644 index 00000000..4c7f0756 --- /dev/null +++ b/src/main/java/ch/naviqore/api/model/Coordinate.java @@ -0,0 +1,63 @@ +package ch.naviqore.api.model; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Getter; + +import java.util.Objects; + +/** + * Coordinate + */ +@Getter +public class Coordinate { + + @JsonProperty("latitude") + private double latitude; + + @JsonProperty("longitude") + private double longitude; + + public Coordinate(double latitude, double longitude) { + this.latitude = latitude; + this.longitude = longitude; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Coordinate coordinate = (Coordinate) o; + return Objects.equals(this.latitude, coordinate.latitude) && Objects.equals(this.longitude, + coordinate.longitude); + } + + @Override + public int hashCode() { + return Objects.hash(latitude, longitude); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class Coordinate {\n"); + sb.append(" latitude: ").append(toIndentedString(latitude)).append("\n"); + sb.append(" longitude: ").append(toIndentedString(longitude)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } +} + diff --git a/src/main/java/ch/naviqore/api/model/Departure.java b/src/main/java/ch/naviqore/api/model/Departure.java new file mode 100644 index 00000000..73ea33e4 --- /dev/null +++ b/src/main/java/ch/naviqore/api/model/Departure.java @@ -0,0 +1,62 @@ +package ch.naviqore.api.model; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Getter; + +import java.util.Objects; + +/** + * Departure + */ +@Getter +public class Departure { + + @JsonProperty("stopTime") + private StopTime stopTime; + + @JsonProperty("trip") + private Trip trip; + + public Departure(StopTime stopTime, Trip trip) { + this.stopTime = stopTime; + this.trip = trip; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Departure departure = (Departure) o; + return Objects.equals(this.stopTime, departure.stopTime) && Objects.equals(this.trip, departure.trip); + } + + @Override + public int hashCode() { + return Objects.hash(stopTime, trip); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class Departure {\n"); + sb.append(" stopTime: ").append(toIndentedString(stopTime)).append("\n"); + sb.append(" trip: ").append(toIndentedString(trip)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } +} + diff --git a/src/main/java/ch/naviqore/api/model/DistanceToStop.java b/src/main/java/ch/naviqore/api/model/DistanceToStop.java new file mode 100644 index 00000000..62600224 --- /dev/null +++ b/src/main/java/ch/naviqore/api/model/DistanceToStop.java @@ -0,0 +1,62 @@ +package ch.naviqore.api.model; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Getter; + +import java.util.Objects; + +/** + * DistanceToStop + */ +@Getter +public class DistanceToStop { + + @JsonProperty("stop") + private Stop stop; + + @JsonProperty("distance") + private double distance; + + public DistanceToStop(Stop stop, double distance) { + this.stop = stop; + this.distance = distance; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + DistanceToStop distanceToStop = (DistanceToStop) o; + return Objects.equals(this.stop, distanceToStop.stop) && Objects.equals(this.distance, distanceToStop.distance); + } + + @Override + public int hashCode() { + return Objects.hash(stop, distance); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class DistanceToStop {\n"); + sb.append(" stop: ").append(toIndentedString(stop)).append("\n"); + sb.append(" distance: ").append(toIndentedString(distance)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } +} + diff --git a/src/main/java/ch/naviqore/api/model/EarliestArrival.java b/src/main/java/ch/naviqore/api/model/EarliestArrival.java new file mode 100644 index 00000000..510741d7 --- /dev/null +++ b/src/main/java/ch/naviqore/api/model/EarliestArrival.java @@ -0,0 +1,71 @@ +package ch.naviqore.api.model; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Getter; +import org.springframework.format.annotation.DateTimeFormat; + +import java.time.LocalDateTime; +import java.util.Objects; + +/** + * EarliestArrival + */ +@Getter +public class EarliestArrival { + + @JsonProperty("stop") + private Stop stop; + + @JsonProperty("arrivalTime") + @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) + private LocalDateTime arrivalTime; + + @JsonProperty("connection") + private Connection connection; + + public EarliestArrival(Stop stop, LocalDateTime arrivalTime, Connection connection) { + this.stop = stop; + this.arrivalTime = arrivalTime; + this.connection = connection; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + EarliestArrival earliestArrival = (EarliestArrival) o; + return Objects.equals(this.stop, earliestArrival.stop) && Objects.equals(this.arrivalTime, + earliestArrival.arrivalTime) && Objects.equals(this.connection, earliestArrival.connection); + } + + @Override + public int hashCode() { + return Objects.hash(stop, arrivalTime, connection); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class EarliestArrival {\n"); + sb.append(" stop: ").append(toIndentedString(stop)).append("\n"); + sb.append(" arrivalTime: ").append(toIndentedString(arrivalTime)).append("\n"); + sb.append(" connection: ").append(toIndentedString(connection)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } +} + diff --git a/src/main/java/ch/naviqore/api/model/Isoline.java b/src/main/java/ch/naviqore/api/model/Isoline.java deleted file mode 100644 index 903e2499..00000000 --- a/src/main/java/ch/naviqore/api/model/Isoline.java +++ /dev/null @@ -1,142 +0,0 @@ -package ch.naviqore.api.model; - -import java.net.URI; -import java.util.Objects; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.annotation.JsonCreator; -import java.time.OffsetDateTime; -import java.util.ArrayList; -import java.util.List; -import org.springframework.format.annotation.DateTimeFormat; -import java.time.OffsetDateTime; -import javax.validation.Valid; -import javax.validation.constraints.*; -import io.swagger.v3.oas.annotations.media.Schema; - - -import java.util.*; - -/** - * Isoline - */ - -public class Isoline { - - @JsonProperty("stopId") - private String stopId; - - @JsonProperty("departureTime") - @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) - private OffsetDateTime departureTime; - - @JsonProperty("coordinates") - @Valid - private List coordinates = null; - - public Isoline stopId(String stopId) { - this.stopId = stopId; - return this; - } - - /** - * Get stopId - * @return stopId - */ - - @Schema(name = "stopId", required = false) - public String getStopId() { - return stopId; - } - - public void setStopId(String stopId) { - this.stopId = stopId; - } - - public Isoline departureTime(OffsetDateTime departureTime) { - this.departureTime = departureTime; - return this; - } - - /** - * Get departureTime - * @return departureTime - */ - @Valid - @Schema(name = "departureTime", required = false) - public OffsetDateTime getDepartureTime() { - return departureTime; - } - - public void setDepartureTime(OffsetDateTime departureTime) { - this.departureTime = departureTime; - } - - public Isoline coordinates(List coordinates) { - this.coordinates = coordinates; - return this; - } - - public Isoline addCoordinatesItem(IsolineCoordinatesInner coordinatesItem) { - if (this.coordinates == null) { - this.coordinates = new ArrayList<>(); - } - this.coordinates.add(coordinatesItem); - return this; - } - - /** - * Get coordinates - * @return coordinates - */ - @Valid - @Schema(name = "coordinates", required = false) - public List getCoordinates() { - return coordinates; - } - - public void setCoordinates(List coordinates) { - this.coordinates = coordinates; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - Isoline isoline = (Isoline) o; - return Objects.equals(this.stopId, isoline.stopId) && - Objects.equals(this.departureTime, isoline.departureTime) && - Objects.equals(this.coordinates, isoline.coordinates); - } - - @Override - public int hashCode() { - return Objects.hash(stopId, departureTime, coordinates); - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("class Isoline {\n"); - sb.append(" stopId: ").append(toIndentedString(stopId)).append("\n"); - sb.append(" departureTime: ").append(toIndentedString(departureTime)).append("\n"); - sb.append(" coordinates: ").append(toIndentedString(coordinates)).append("\n"); - sb.append("}"); - return sb.toString(); - } - - /** - * Convert the given object to string with each line indented by 4 spaces - * (except the first line). - */ - private String toIndentedString(Object o) { - if (o == null) { - return "null"; - } - return o.toString().replace("\n", "\n "); - } -} - diff --git a/src/main/java/ch/naviqore/api/model/IsolineCoordinatesInner.java b/src/main/java/ch/naviqore/api/model/IsolineCoordinatesInner.java deleted file mode 100644 index c8f6d90a..00000000 --- a/src/main/java/ch/naviqore/api/model/IsolineCoordinatesInner.java +++ /dev/null @@ -1,102 +0,0 @@ -package ch.naviqore.api.model; - -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.annotation.JsonTypeName; -import io.swagger.v3.oas.annotations.media.Schema; - -import javax.validation.Valid; -import javax.validation.constraints.*; -import java.math.BigDecimal; -import java.util.Objects; - -/** - * IsolineCoordinatesInner - */ - -@JsonTypeName("Isoline_coordinates_inner") -public class IsolineCoordinatesInner { - - @JsonProperty("latitude") - private BigDecimal latitude; - - @JsonProperty("longitude") - private BigDecimal longitude; - - public IsolineCoordinatesInner latitude(BigDecimal latitude) { - this.latitude = latitude; - return this; - } - - /** - * Get latitude - * @return latitude - */ - @Valid - @Schema(name = "latitude", required = false) - public BigDecimal getLatitude() { - return latitude; - } - - public void setLatitude(BigDecimal latitude) { - this.latitude = latitude; - } - - public IsolineCoordinatesInner longitude(BigDecimal longitude) { - this.longitude = longitude; - return this; - } - - /** - * Get longitude - * @return longitude - */ - @Valid - @Schema(name = "longitude", required = false) - public BigDecimal getLongitude() { - return longitude; - } - - public void setLongitude(BigDecimal longitude) { - this.longitude = longitude; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - IsolineCoordinatesInner isolineCoordinatesInner = (IsolineCoordinatesInner) o; - return Objects.equals(this.latitude, isolineCoordinatesInner.latitude) && - Objects.equals(this.longitude, isolineCoordinatesInner.longitude); - } - - @Override - public int hashCode() { - return Objects.hash(latitude, longitude); - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("class IsolineCoordinatesInner {\n"); - sb.append(" latitude: ").append(toIndentedString(latitude)).append("\n"); - sb.append(" longitude: ").append(toIndentedString(longitude)).append("\n"); - sb.append("}"); - return sb.toString(); - } - - /** - * Convert the given object to string with each line indented by 4 spaces - * (except the first line). - */ - private String toIndentedString(Object o) { - if (o == null) { - return "null"; - } - return o.toString().replace("\n", "\n "); - } -} - diff --git a/src/main/java/ch/naviqore/api/model/Leg.java b/src/main/java/ch/naviqore/api/model/Leg.java index c51fedf1..0e7cbb08 100644 --- a/src/main/java/ch/naviqore/api/model/Leg.java +++ b/src/main/java/ch/naviqore/api/model/Leg.java @@ -1,194 +1,99 @@ package ch.naviqore.api.model; import com.fasterxml.jackson.annotation.JsonProperty; -import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Getter; +import org.springframework.format.annotation.DateTimeFormat; -import javax.validation.constraints.*; +import java.time.LocalDateTime; import java.util.Objects; /** * Leg */ - +@Getter public class Leg { - @JsonProperty("id") - private String id; - - @JsonProperty("fromStopId") - private String fromStopId; - - @JsonProperty("toStopId") - private String toStopId; - - @JsonProperty("departureTime") - private String departureTime; - - @JsonProperty("arrivalTime") - private String arrivalTime; - - @JsonProperty("type") - private String type; - - public Leg id(String id) { - this.id = id; - return this; - } - - /** - * Get id - * @return id - */ - - @Schema(name = "id", required = false) - public String getId() { - return id; - } - - public void setId(String id) { - this.id = id; - } - - public Leg fromStopId(String fromStopId) { - this.fromStopId = fromStopId; - return this; - } - - /** - * Get fromStopId - * @return fromStopId - */ - - @Schema(name = "fromStopId", required = false) - public String getFromStopId() { - return fromStopId; - } - - public void setFromStopId(String fromStopId) { - this.fromStopId = fromStopId; - } - - public Leg toStopId(String toStopId) { - this.toStopId = toStopId; - return this; - } - - /** - * Get toStopId - * @return toStopId - */ - - @Schema(name = "toStopId", required = false) - public String getToStopId() { - return toStopId; - } - - public void setToStopId(String toStopId) { - this.toStopId = toStopId; - } - - public Leg departureTime(String departureTime) { - this.departureTime = departureTime; - return this; - } - - /** - * Get departureTime - * @return departureTime - */ - - @Schema(name = "departureTime", required = false) - public String getDepartureTime() { - return departureTime; - } - - public void setDepartureTime(String departureTime) { - this.departureTime = departureTime; - } - - public Leg arrivalTime(String arrivalTime) { - this.arrivalTime = arrivalTime; - return this; - } - - /** - * Get arrivalTime - * @return arrivalTime - */ - - @Schema(name = "arrivalTime", required = false) - public String getArrivalTime() { - return arrivalTime; - } - - public void setArrivalTime(String arrivalTime) { - this.arrivalTime = arrivalTime; - } - - public Leg type(String type) { - this.type = type; - return this; - } - - /** - * Get type - * @return type - */ - - @Schema(name = "type", required = false) - public String getType() { - return type; - } - - public void setType(String type) { - this.type = type; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; + @JsonProperty("from") + private Coordinate from; + + @JsonProperty("to") + private Coordinate to; + + @JsonProperty("fromStop") + private Stop fromStop; + + @JsonProperty("toStop") + private Stop toStop; + + @JsonProperty("type") + private LegType type; + + @JsonProperty("departureTime") + @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) + private LocalDateTime departureTime; + + @JsonProperty("arrivalTime") + @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) + private LocalDateTime arrivalTime; + + @JsonProperty("trip") + private Trip trip; + + public Leg(Coordinate from, Coordinate to, Stop fromStop, Stop toStop, LegType type, LocalDateTime departureTime, + LocalDateTime arrivalTime, Trip trip) { + this.from = from; + this.to = to; + this.fromStop = fromStop; + this.toStop = toStop; + this.type = type; + this.departureTime = departureTime; + this.arrivalTime = arrivalTime; + this.trip = trip; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Leg leg = (Leg) o; + return Objects.equals(this.from, leg.from) && Objects.equals(this.to, leg.to) && Objects.equals(this.fromStop, + leg.fromStop) && Objects.equals(this.toStop, leg.toStop) && Objects.equals(this.type, + leg.type) && Objects.equals(this.departureTime, leg.departureTime) && Objects.equals(this.arrivalTime, + leg.arrivalTime); } - if (o == null || getClass() != o.getClass()) { - return false; + + @Override + public int hashCode() { + return Objects.hash(from, to, fromStop, toStop, type, departureTime, arrivalTime); } - Leg leg = (Leg) o; - return Objects.equals(this.id, leg.id) && - Objects.equals(this.fromStopId, leg.fromStopId) && - Objects.equals(this.toStopId, leg.toStopId) && - Objects.equals(this.departureTime, leg.departureTime) && - Objects.equals(this.arrivalTime, leg.arrivalTime) && - Objects.equals(this.type, leg.type); - } - - @Override - public int hashCode() { - return Objects.hash(id, fromStopId, toStopId, departureTime, arrivalTime, type); - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("class Leg {\n"); - sb.append(" id: ").append(toIndentedString(id)).append("\n"); - sb.append(" fromStopId: ").append(toIndentedString(fromStopId)).append("\n"); - sb.append(" toStopId: ").append(toIndentedString(toStopId)).append("\n"); - sb.append(" departureTime: ").append(toIndentedString(departureTime)).append("\n"); - sb.append(" arrivalTime: ").append(toIndentedString(arrivalTime)).append("\n"); - sb.append(" type: ").append(toIndentedString(type)).append("\n"); - sb.append("}"); - return sb.toString(); - } - - /** - * Convert the given object to string with each line indented by 4 spaces - * (except the first line). - */ - private String toIndentedString(Object o) { - if (o == null) { - return "null"; + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class Leg {\n"); + sb.append(" from: ").append(toIndentedString(from)).append("\n"); + sb.append(" to: ").append(toIndentedString(to)).append("\n"); + sb.append(" fromStop: ").append(toIndentedString(fromStop)).append("\n"); + sb.append(" toStop: ").append(toIndentedString(toStop)).append("\n"); + sb.append(" type: ").append(toIndentedString(type)).append("\n"); + sb.append(" departureTime: ").append(toIndentedString(departureTime)).append("\n"); + sb.append(" arrivalTime: ").append(toIndentedString(arrivalTime)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); } - return o.toString().replace("\n", "\n "); - } } diff --git a/src/main/java/ch/naviqore/api/model/LegType.java b/src/main/java/ch/naviqore/api/model/LegType.java new file mode 100644 index 00000000..54a41fc2 --- /dev/null +++ b/src/main/java/ch/naviqore/api/model/LegType.java @@ -0,0 +1,42 @@ +package ch.naviqore.api.model; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +/** + * Gets or Sets LegType + */ + +public enum LegType { + + WALK("WALK"), + + ROUTE("ROUTE"); + + private final String value; + + LegType(String value) { + this.value = value; + } + + @JsonValue + public String getValue() { + return value; + } + + @Override + public String toString() { + return String.valueOf(value); + } + + @JsonCreator + public static LegType fromValue(String value) { + for (LegType b : LegType.values()) { + if (b.value.equals(value)) { + return b; + } + } + throw new IllegalArgumentException("Unexpected value '" + value + "'"); + } +} + diff --git a/src/main/java/ch/naviqore/api/model/Route.java b/src/main/java/ch/naviqore/api/model/Route.java index 06ae30c8..33559653 100644 --- a/src/main/java/ch/naviqore/api/model/Route.java +++ b/src/main/java/ch/naviqore/api/model/Route.java @@ -1,98 +1,74 @@ package ch.naviqore.api.model; import com.fasterxml.jackson.annotation.JsonProperty; -import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Getter; -import javax.validation.constraints.*; import java.util.Objects; /** * Route */ +@Getter public class Route { - @JsonProperty("id") - private String id; + @JsonProperty("id") + private String id; - @JsonProperty("name") - private String name; + @JsonProperty("name") + private String name; - public Route id(String id) { - this.id = id; - return this; - } + @JsonProperty("shortName") + private String shortName; - /** - * Get id - * @return id - */ - - @Schema(name = "id", required = false) - public String getId() { - return id; - } + @JsonProperty("transportMode") + private String transportMode; - public void setId(String id) { - this.id = id; - } - - public Route name(String name) { - this.name = name; - return this; - } - - /** - * Get name - * @return name - */ - - @Schema(name = "name", required = false) - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; + public Route(String id, String name, String shortName, String transportMode) { + this.id = id; + this.name = name; + this.shortName = shortName; + this.transportMode = transportMode; } - if (o == null || getClass() != o.getClass()) { - return false; + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Route route = (Route) o; + return Objects.equals(this.id, route.id) && Objects.equals(this.name, route.name) && Objects.equals( + this.shortName, route.shortName) && Objects.equals(this.transportMode, route.transportMode); } - Route route = (Route) o; - return Objects.equals(this.id, route.id) && - Objects.equals(this.name, route.name); - } - @Override - public int hashCode() { - return Objects.hash(id, name); - } + @Override + public int hashCode() { + return Objects.hash(id, name, shortName, transportMode); + } - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("class Route {\n"); - sb.append(" id: ").append(toIndentedString(id)).append("\n"); - sb.append(" name: ").append(toIndentedString(name)).append("\n"); - sb.append("}"); - return sb.toString(); - } + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class Route {\n"); + sb.append(" id: ").append(toIndentedString(id)).append("\n"); + sb.append(" name: ").append(toIndentedString(name)).append("\n"); + sb.append(" shortName: ").append(toIndentedString(shortName)).append("\n"); + sb.append(" transportMode: ").append(toIndentedString(transportMode)).append("\n"); + sb.append("}"); + return sb.toString(); + } - /** - * Convert the given object to string with each line indented by 4 spaces - * (except the first line). - */ - private String toIndentedString(Object o) { - if (o == null) { - return "null"; + /** + * Convert the given object to string with each line indented by 4 spaces (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); } - return o.toString().replace("\n", "\n "); - } } diff --git a/src/main/java/ch/naviqore/api/model/SearchType.java b/src/main/java/ch/naviqore/api/model/SearchType.java new file mode 100644 index 00000000..7a144644 --- /dev/null +++ b/src/main/java/ch/naviqore/api/model/SearchType.java @@ -0,0 +1,48 @@ +package ch.naviqore.api.model; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +/** + * Gets or Sets SearchType + */ + +public enum SearchType { + + EXACT("EXACT"), + + STARTS_WITH("STARTS_WITH"), + + CONTAINS("CONTAINS"), + + ENDS_WITH("ENDS_WITH"), + + FUZZY("FUZZY"); + + private final String value; + + SearchType(String value) { + this.value = value; + } + + @JsonValue + public String getValue() { + return value; + } + + @Override + public String toString() { + return String.valueOf(value); + } + + @JsonCreator + public static SearchType fromValue(String value) { + for (SearchType b : SearchType.values()) { + if (b.value.equals(value)) { + return b; + } + } + throw new IllegalArgumentException("Unexpected value '" + value + "'"); + } +} + diff --git a/src/main/java/ch/naviqore/api/model/Stop.java b/src/main/java/ch/naviqore/api/model/Stop.java index fd76ac6a..63f425cc 100644 --- a/src/main/java/ch/naviqore/api/model/Stop.java +++ b/src/main/java/ch/naviqore/api/model/Stop.java @@ -1,182 +1,69 @@ package ch.naviqore.api.model; import com.fasterxml.jackson.annotation.JsonProperty; -import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Getter; -import javax.validation.Valid; -import javax.validation.constraints.*; -import java.math.BigDecimal; -import java.util.ArrayList; -import java.util.List; import java.util.Objects; /** * Stop */ -public class Stop { - - @JsonProperty("id") - private String id; - - @JsonProperty("name") - private String name; - - @JsonProperty("latitude") - private BigDecimal latitude; - - @JsonProperty("longitude") - private BigDecimal longitude; - - @JsonProperty("routes") - @Valid - private List routes = null; - - public Stop id(String id) { - this.id = id; - return this; - } - - /** - * Get id - * @return id - */ - - @Schema(name = "id", required = false) - public String getId() { - return id; - } - - public void setId(String id) { - this.id = id; - } - - public Stop name(String name) { - this.name = name; - return this; - } - - /** - * Get name - * @return name - */ - - @Schema(name = "name", required = false) - public String getName() { - return name; - } - public void setName(String name) { - this.name = name; - } - - public Stop latitude(BigDecimal latitude) { - this.latitude = latitude; - return this; - } - - /** - * Get latitude - * @return latitude - */ - @Valid - @Schema(name = "latitude", required = false) - public BigDecimal getLatitude() { - return latitude; - } - - public void setLatitude(BigDecimal latitude) { - this.latitude = latitude; - } - - public Stop longitude(BigDecimal longitude) { - this.longitude = longitude; - return this; - } +@Getter +public class Stop { - /** - * Get longitude - * @return longitude - */ - @Valid - @Schema(name = "longitude", required = false) - public BigDecimal getLongitude() { - return longitude; - } + @JsonProperty("id") + private String id; - public void setLongitude(BigDecimal longitude) { - this.longitude = longitude; - } + @JsonProperty("name") + private String name; - public Stop routes(List routes) { - this.routes = routes; - return this; - } + @JsonProperty("coordinates") + private Coordinate coordinates; - public Stop addRoutesItem(Route routesItem) { - if (this.routes == null) { - this.routes = new ArrayList<>(); + public Stop(String id, String name, Coordinate coordinates) { + this.id = id; + this.name = name; + this.coordinates = coordinates; } - this.routes.add(routesItem); - return this; - } - /** - * Get routes - * @return routes - */ - @Valid - @Schema(name = "routes", required = false) - public List getRoutes() { - return routes; - } - - public void setRoutes(List routes) { - this.routes = routes; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Stop stop = (Stop) o; + return Objects.equals(this.id, stop.id) && Objects.equals(this.name, stop.name) && Objects.equals( + this.coordinates, stop.coordinates); } - Stop stop = (Stop) o; - return Objects.equals(this.id, stop.id) && - Objects.equals(this.name, stop.name) && - Objects.equals(this.latitude, stop.latitude) && - Objects.equals(this.longitude, stop.longitude) && - Objects.equals(this.routes, stop.routes); - } - @Override - public int hashCode() { - return Objects.hash(id, name, latitude, longitude, routes); - } + @Override + public int hashCode() { + return Objects.hash(id, name, coordinates); + } - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("class Stop {\n"); - sb.append(" id: ").append(toIndentedString(id)).append("\n"); - sb.append(" name: ").append(toIndentedString(name)).append("\n"); - sb.append(" latitude: ").append(toIndentedString(latitude)).append("\n"); - sb.append(" longitude: ").append(toIndentedString(longitude)).append("\n"); - sb.append(" routes: ").append(toIndentedString(routes)).append("\n"); - sb.append("}"); - return sb.toString(); - } + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class Stop {\n"); + sb.append(" id: ").append(toIndentedString(id)).append("\n"); + sb.append(" name: ").append(toIndentedString(name)).append("\n"); + sb.append(" coordinates: ").append(toIndentedString(coordinates)).append("\n"); + sb.append("}"); + return sb.toString(); + } - /** - * Convert the given object to string with each line indented by 4 spaces - * (except the first line). - */ - private String toIndentedString(Object o) { - if (o == null) { - return "null"; + /** + * Convert the given object to string with each line indented by 4 spaces (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); } - return o.toString().replace("\n", "\n "); - } } diff --git a/src/main/java/ch/naviqore/api/model/StopTime.java b/src/main/java/ch/naviqore/api/model/StopTime.java index 256321c6..4ed4473e 100644 --- a/src/main/java/ch/naviqore/api/model/StopTime.java +++ b/src/main/java/ch/naviqore/api/model/StopTime.java @@ -1,145 +1,77 @@ package ch.naviqore.api.model; import com.fasterxml.jackson.annotation.JsonProperty; -import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Getter; +import org.springframework.format.annotation.DateTimeFormat; +import java.time.LocalDateTime; import java.util.Objects; /** * StopTime */ - +@Getter public class StopTime { - @JsonProperty("tripId") - private String tripId; - - @JsonProperty("stopId") - private String stopId; - - @JsonProperty("arrivalTime") - private String arrivalTime; - - @JsonProperty("departureTime") - private String departureTime; - - public StopTime tripId(String tripId) { - this.tripId = tripId; - return this; - } - - /** - * Get tripId - * @return tripId - */ - - @Schema(name = "tripId", required = false) - public String getTripId() { - return tripId; - } - - public void setTripId(String tripId) { - this.tripId = tripId; - } - - public StopTime stopId(String stopId) { - this.stopId = stopId; - return this; - } - - /** - * Get stopId - * @return stopId - */ - - @Schema(name = "stopId", required = false) - public String getStopId() { - return stopId; - } + @JsonProperty("stop") + private Stop stop; - public void setStopId(String stopId) { - this.stopId = stopId; - } + @JsonProperty("arrivalTime") + @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) + private LocalDateTime arrivalTime; - public StopTime arrivalTime(String arrivalTime) { - this.arrivalTime = arrivalTime; - return this; - } + @JsonProperty("departureTime") + @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) + private LocalDateTime departureTime; - /** - * Get arrivalTime - * @return arrivalTime - */ - - @Schema(name = "arrivalTime", required = false) - public String getArrivalTime() { - return arrivalTime; - } - - public void setArrivalTime(String arrivalTime) { - this.arrivalTime = arrivalTime; - } - - public StopTime departureTime(String departureTime) { - this.departureTime = departureTime; - return this; - } - - /** - * Get departureTime - * @return departureTime - */ - - @Schema(name = "departureTime", required = false) - public String getDepartureTime() { - return departureTime; - } - - public void setDepartureTime(String departureTime) { - this.departureTime = departureTime; - } + public StopTime(Stop stop, LocalDateTime arrivalTime, LocalDateTime departureTime) { + this.stop = stop; + this.arrivalTime = arrivalTime; + this.departureTime = departureTime; + } - @Override - public boolean equals(Object o) { - if (this == o) { - return true; + public StopTime stop(Stop stop) { + this.stop = stop; + return this; } - if (o == null || getClass() != o.getClass()) { - return false; + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + StopTime stopTime = (StopTime) o; + return Objects.equals(this.stop, stopTime.stop) && Objects.equals(this.arrivalTime, + stopTime.arrivalTime) && Objects.equals(this.departureTime, stopTime.departureTime); } - StopTime stopTime = (StopTime) o; - return Objects.equals(this.tripId, stopTime.tripId) && - Objects.equals(this.stopId, stopTime.stopId) && - Objects.equals(this.arrivalTime, stopTime.arrivalTime) && - Objects.equals(this.departureTime, stopTime.departureTime); - } - @Override - public int hashCode() { - return Objects.hash(tripId, stopId, arrivalTime, departureTime); - } + @Override + public int hashCode() { + return Objects.hash(stop, arrivalTime, departureTime); + } - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("class StopTime {\n"); - sb.append(" tripId: ").append(toIndentedString(tripId)).append("\n"); - sb.append(" stopId: ").append(toIndentedString(stopId)).append("\n"); - sb.append(" arrivalTime: ").append(toIndentedString(arrivalTime)).append("\n"); - sb.append(" departureTime: ").append(toIndentedString(departureTime)).append("\n"); - sb.append("}"); - return sb.toString(); - } + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class StopTime {\n"); + sb.append(" stop: ").append(toIndentedString(stop)).append("\n"); + sb.append(" arrivalTime: ").append(toIndentedString(arrivalTime)).append("\n"); + sb.append(" departureTime: ").append(toIndentedString(departureTime)).append("\n"); + sb.append("}"); + return sb.toString(); + } - /** - * Convert the given object to string with each line indented by 4 spaces - * (except the first line). - */ - private String toIndentedString(Object o) { - if (o == null) { - return "null"; + /** + * Convert the given object to string with each line indented by 4 spaces (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); } - return o.toString().replace("\n", "\n "); - } } diff --git a/src/main/java/ch/naviqore/api/model/Trip.java b/src/main/java/ch/naviqore/api/model/Trip.java new file mode 100644 index 00000000..e874f1a7 --- /dev/null +++ b/src/main/java/ch/naviqore/api/model/Trip.java @@ -0,0 +1,69 @@ +package ch.naviqore.api.model; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Getter; + +import java.util.List; +import java.util.Objects; + +/** + * Trip + */ +@Getter +public class Trip { + + @JsonProperty("headSign") + private String headSign; + + @JsonProperty("route") + private Route route; + + @JsonProperty("stopTimes") + private List stopTimes; + + public Trip(String headSign, Route route, List stopTimes) { + this.headSign = headSign; + this.route = route; + this.stopTimes = stopTimes; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Trip trip = (Trip) o; + return Objects.equals(this.headSign, trip.headSign) && Objects.equals(this.route, trip.route) && Objects.equals( + this.stopTimes, trip.stopTimes); + } + + @Override + public int hashCode() { + return Objects.hash(headSign, route, stopTimes); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class Trip {\n"); + sb.append(" headSign: ").append(toIndentedString(headSign)).append("\n"); + sb.append(" route: ").append(toIndentedString(route)).append("\n"); + sb.append(" stopTimes: ").append(toIndentedString(stopTimes)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } +} + diff --git a/src/main/resources/api/openapi.yaml b/src/main/resources/api/openapi.yaml index adef953d..0ce5b572 100644 --- a/src/main/resources/api/openapi.yaml +++ b/src/main/resources/api/openapi.yaml @@ -289,6 +289,8 @@ components: arrivalTime: type: string format: date-time + trip: + $ref: '#/components/schemas/Trip' EarliestArrival: type: object properties: From cec353699c1c0bd7ffaf7979d0e8dd3a88afa6f7 Mon Sep 17 00:00:00 2001 From: Lukas Connolly Date: Sat, 25 May 2024 02:56:11 +0200 Subject: [PATCH 05/11] REFACTOR: NAV-16 - Remove test endpoint. --- src/main/java/ch/naviqore/api/controller/Test.java | 14 -------------- 1 file changed, 14 deletions(-) delete mode 100644 src/main/java/ch/naviqore/api/controller/Test.java diff --git a/src/main/java/ch/naviqore/api/controller/Test.java b/src/main/java/ch/naviqore/api/controller/Test.java deleted file mode 100644 index a4a1c855..00000000 --- a/src/main/java/ch/naviqore/api/controller/Test.java +++ /dev/null @@ -1,14 +0,0 @@ -package ch.naviqore.api.controller; - -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RestController; - -@RestController -public class Test { - - @GetMapping("/test") - public String testEndpoint() { - return "Hello, World!"; - } - -} From 3e45e73114b59396664305e4b7fd9f114bd05bde Mon Sep 17 00:00:00 2001 From: Lukas Connolly Date: Sun, 26 May 2024 15:24:22 +0200 Subject: [PATCH 06/11] =?UTF-8?q?ENH:=20NAV-16=20-=20Add=20stops=20around?= =?UTF-8?q?=20Z=C3=BCrich=20to=20dummy=20data=20and=20improve=20connection?= =?UTF-8?q?=20generaton.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ch/naviqore/api/controller/DummyData.java | 107 +++++++++--------- 1 file changed, 52 insertions(+), 55 deletions(-) diff --git a/src/main/java/ch/naviqore/api/controller/DummyData.java b/src/main/java/ch/naviqore/api/controller/DummyData.java index e8152d8e..b48ce330 100644 --- a/src/main/java/ch/naviqore/api/controller/DummyData.java +++ b/src/main/java/ch/naviqore/api/controller/DummyData.java @@ -11,36 +11,29 @@ public class DummyData { public static List getStops() { List dtos = new ArrayList<>(); - dtos.add(new Stop("Stop-1", "Train Station", new Coordinate(47.9, 8.0))); - dtos.add(new Stop("Stop-2", "Bus Station", new Coordinate(47.95, 8.05))); - dtos.add(new Stop("Stop-3", "Tram Station", new Coordinate(48.0, 8.1))); - dtos.add(new Stop("Stop-4", "Central Station", new Coordinate(48.1, 8.0))); - dtos.add(new Stop("Stop-5", "East Station", new Coordinate(47.9, 7.95))); - dtos.add(new Stop("Stop-6", "West Station", new Coordinate(48.15, 8.1))); - dtos.add(new Stop("Stop-7", "North Station", new Coordinate(48.05, 7.9))); - dtos.add(new Stop("Stop-8", "South Station", new Coordinate(48.2, 8.05))); - dtos.add(new Stop("Stop-9", "City Center", new Coordinate(47.95, 8.1))); - dtos.add(new Stop("Stop-10", "Main Square", new Coordinate(48.0, 8.05))); - dtos.add(new Stop("Stop-11", "University", new Coordinate(48.1, 7.95))); - dtos.add(new Stop("Stop-12", "Airport", new Coordinate(47.9, 8.1))); - dtos.add(new Stop("Stop-13", "Harbor", new Coordinate(48.2, 7.9))); - dtos.add(new Stop("Stop-14", "Market Place", new Coordinate(48.05, 8.0))); - dtos.add(new Stop("Stop-15", "Old Town", new Coordinate(47.95, 7.9))); - dtos.add(new Stop("Stop-16", "Industrial Park", new Coordinate(48.0, 8.1))); - dtos.add(new Stop("Stop-17", "Business District", new Coordinate(48.1, 8.05))); - dtos.add(new Stop("Stop-18", "Residential Area", new Coordinate(48.2, 8.0))); - dtos.add(new Stop("Stop-19", "Historic Site", new Coordinate(48.0, 7.95))); - dtos.add(new Stop("Stop-20", "Tech Park", new Coordinate(47.9, 8.05))); - dtos.add(new Stop("Stop-21", "City Hall", new Coordinate(48.1, 7.9))); - dtos.add(new Stop("Stop-22", "Library", new Coordinate(48.2, 8.1))); - dtos.add(new Stop("Stop-23", "Museum", new Coordinate(47.95, 8.0))); - dtos.add(new Stop("Stop-24", "Stadium", new Coordinate(48.05, 8.1))); - dtos.add(new Stop("Stop-25", "Aquarium", new Coordinate(48.0, 8.0))); - dtos.add(new Stop("Stop-26", "Zoo", new Coordinate(48.1, 8.05))); - dtos.add(new Stop("Stop-27", "Botanical Garden", new Coordinate(48.2, 7.95))); - dtos.add(new Stop("Stop-28", "Concert Hall", new Coordinate(48.05, 7.9))); - dtos.add(new Stop("Stop-29", "Exhibition Center", new Coordinate(48.0, 8.1))); - dtos.add(new Stop("Stop-30", "Convention Center", new Coordinate(47.9, 8.0))); + dtos.add(new Stop("Stop-1", "Zürich, Klinik Hirslanden", new Coordinate(47.35189719, 8.576602294))); + dtos.add(new Stop("Stop-2", "Brüttisellen, Gemeindehaus", new Coordinate(47.42036924, 8.628830345))); + dtos.add(new Stop("Stop-3", "Hausen a.A., Post A", new Coordinate(47.24489999, 8.532728576))); + dtos.add(new Stop("Stop-4", "Zürich, Bahnhof Stadelhofen", new Coordinate(47.36616091, 8.5472723))); + dtos.add(new Stop("Stop-5", "Spital Zollikerberg", new Coordinate(47.34735681, 8.596634725))); + dtos.add(new Stop("Stop-6", "Zürich, Central Polybahn", new Coordinate(47.37652769, 8.544352776))); + dtos.add(new Stop("Stop-7", "Uster, Buchholz", new Coordinate(47.35874961, 8.729172162))); + dtos.add(new Stop("Stop-8", "Zürich, Triemli", new Coordinate(47.3680227, 8.495682053))); + dtos.add(new Stop("Stop-9", "Winterthur, Hauptbahnhof", new Coordinate(47.49938025, 8.723908035))); + dtos.add(new Stop("Stop-10", "Zürich Flughafen, Bahnhof", new Coordinate(47.45027729, 8.56405283))); + dtos.add(new Stop("Stop-11", "Zürich, Schwamendingerplatz", new Coordinate(47.40487989, 8.571481897))); + dtos.add(new Stop("Stop-12", "Roswiesen", new Coordinate(47.40295252, 8.576979587))); + dtos.add(new Stop("Stop-13", "Siemens", new Coordinate(47.37846819, 8.494002204))); + dtos.add(new Stop("Stop-14", "Stauffacher", new Coordinate(47.37342517, 8.529252096))); + dtos.add(new Stop("Stop-15", "Sternen Oerlikon", new Coordinate(47.41007188, 8.546230254))); + dtos.add(new Stop("Stop-16", "Zoo", new Coordinate(47.38157041, 8.571553762))); + dtos.add(new Stop("Stop-17", "Universität Irchel", new Coordinate(47.39616056, 8.544828883))); + dtos.add(new Stop("Stop-18", "Benglen, Gerlisbrunnen", new Coordinate(47.36092808, 8.632872764))); + dtos.add(new Stop("Stop-19", "Winterthur, Grüzenstrasse", new Coordinate(47.49825747, 8.744587252))); + dtos.add(new Stop("Stop-20", "Zürich, Bahnhof Wollishofen", new Coordinate(47.34825762, 8.533294514))); + dtos.add(new Stop("Stop-21", "Elsau, Melcher", new Coordinate(47.50171676, 8.787230279))); + dtos.add(new Stop("Stop-22", "Wetzikon ZH, Walfershausen", new Coordinate(47.32205504, 8.797336326))); + dtos.add(new Stop("Stop-23", "Hombrechtikon, Tobel", new Coordinate(47.25379065, 8.780986988))); return dtos; } @@ -138,7 +131,7 @@ private static Connection buildSimpleDummyConnection(Stop from, Stop to, LocalDa private static Connection buildTwoLegDummyConnection(Stop from, Stop to, LocalDateTime departureTime) { - Stop stopBetween = getStopInBetweenStops(from, to); + Stop stopBetween = getStopInBetweenStops(from, to, 2); if (stopBetween == null) { return buildSimpleDummyConnection(from, to, departureTime); @@ -155,14 +148,14 @@ private static Connection buildTwoLegDummyConnection(Stop from, Stop to, LocalDa private static Connection buildThreeLegDummyConnectionWithFootpath(Stop from, Stop to, LocalDateTime departureTime) { - Stop stopBetween = getStopInBetweenStops(from, to); + Stop stopBetween = getStopInBetweenStops(from, to, 2); if (stopBetween == null) { return buildTwoLegDummyConnection(from, to, departureTime); } List closestStops = getNearestStops(stopBetween.getCoordinates().getLatitude(), - stopBetween.getCoordinates().getLongitude(), 5000, 10); + stopBetween.getCoordinates().getLongitude(), Integer.MAX_VALUE, 4); Stop closestStop = null; @@ -195,32 +188,36 @@ private static Connection buildThreeLegDummyConnectionWithFootpath(Stop from, St return new Connection(legs); } - private static Stop getStopInBetweenStops(Stop from, Stop to) { - List stops = getStops(); - // get all stops between from and to - List stopsBetween = new ArrayList<>(); - for (Stop stop : stops) { - if (stop.equals(from) || stop.equals(to)) { - continue; - } - double maxLat = Math.max(from.getCoordinates().getLatitude(), to.getCoordinates().getLatitude()); - double minLat = Math.min(from.getCoordinates().getLatitude(), to.getCoordinates().getLatitude()); - double maxLon = Math.max(from.getCoordinates().getLongitude(), to.getCoordinates().getLongitude()); - double minLon = Math.min(from.getCoordinates().getLongitude(), to.getCoordinates().getLongitude()); - if (stop.getCoordinates().getLatitude() > minLat && stop.getCoordinates() - .getLatitude() < maxLat && stop.getCoordinates().getLongitude() > minLon && stop.getCoordinates() - .getLongitude() < maxLon) { - stopsBetween.add(stop); - System.out.println("Stop between: " + stop.getName()); + private static Stop getStopInBetweenStops(Stop from, Stop to, int randomness) { + return getStopInBetweenStops(from, to, randomness, List.of(from, to)); + } + + private static Stop getStopInBetweenStops(Stop from, Stop to, int randomness, List exclusionStops) { + + // get coordinate of the center of the two stops + double centerLat = (from.getCoordinates().getLatitude() + to.getCoordinates().getLatitude()) / 2; + double centerLon = (from.getCoordinates().getLongitude() + to.getCoordinates().getLongitude()) / 2; + Coordinate center = new Coordinate(centerLat, centerLon); + + List closestStops = getNearestStops(center.getLatitude(), center.getLongitude(), + Integer.MAX_VALUE, 3+randomness); + + // random sort to get different results + closestStops.sort((a, b) -> { + if (a.getStop().equals(b.getStop()) && a.getDistance() == b.getDistance()) { + return 0; } - } + return Math.random() < 0.5 ? -1 : 1; + }); - if (stopsBetween.isEmpty()) { - return null; - //return stops.get((int) (Math.random() * stops.size())); + for (DistanceToStop distanceToStop : closestStops) { + if (exclusionStops.contains(distanceToStop.getStop())) { + continue; + } + return distanceToStop.getStop(); } - return stopsBetween.get((int) (Math.random() * stopsBetween.size())); + return null; } private static Leg buildTripDummyLeg(Stop from, Stop to, LocalDateTime departureTime) { From 145f02da9f65e32b6d86fd5db4636a7e1e7e4f41 Mon Sep 17 00:00:00 2001 From: Lukas Connolly Date: Sun, 26 May 2024 16:12:36 +0200 Subject: [PATCH 07/11] FIX: NAV-16 - Make dummy departures be random offseted and make departureTime parameter consistent over endpoints. --- .../ch/naviqore/api/controller/DummyData.java | 27 ++++++++++++++----- .../api/controller/ScheduleController.java | 4 +-- src/main/resources/api/openapi.yaml | 2 +- 3 files changed, 23 insertions(+), 10 deletions(-) diff --git a/src/main/java/ch/naviqore/api/controller/DummyData.java b/src/main/java/ch/naviqore/api/controller/DummyData.java index b48ce330..21d8b638 100644 --- a/src/main/java/ch/naviqore/api/controller/DummyData.java +++ b/src/main/java/ch/naviqore/api/controller/DummyData.java @@ -6,9 +6,16 @@ import java.util.ArrayList; import java.util.Comparator; import java.util.List; +import java.util.Random; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class DummyData { + static Random random = new Random(); + private static final Logger logger = LoggerFactory.getLogger(DummyData.class); + public static List getStops() { List dtos = new ArrayList<>(); dtos.add(new Stop("Stop-1", "Zürich, Klinik Hirslanden", new Coordinate(47.35189719, 8.576602294))); @@ -207,7 +214,7 @@ private static Stop getStopInBetweenStops(Stop from, Stop to, int randomness, Li if (a.getStop().equals(b.getStop()) && a.getDistance() == b.getDistance()) { return 0; } - return Math.random() < 0.5 ? -1 : 1; + return random.nextInt(3) < 2 ? -1 : 1; }); for (DistanceToStop distanceToStop : closestStops) { @@ -224,28 +231,33 @@ private static Leg buildTripDummyLeg(Stop from, Stop to, LocalDateTime departure double distance = approximateDistance(from.getCoordinates(), to.getCoordinates()); // get route randomly List routes = getRoutes(); - Route route = routes.get((int) (Math.random() * routes.size())); + int routeIndex = random.nextInt(routes.size()); + Route route = routes.get(routeIndex); + int speed = 1000; // meters per minute if (route.getTransportMode().equals("Train")) { speed = 2000; } int travelTime = (int) (distance / speed); // in minutes - LocalDateTime tripDepartureTime = departureTime.plusMinutes((int) (Math.random() * 20)); + int departureOffset = random.nextInt(20); + LocalDateTime tripDepartureTime = departureTime.plusMinutes(departureOffset); LocalDateTime tripArrivalTime = tripDepartureTime.plusMinutes(travelTime); ArrayList stopTimes = new ArrayList<>(); - stopTimes.add(new StopTime(from, departureTime, tripDepartureTime)); + stopTimes.add(new StopTime(from, tripDepartureTime, tripDepartureTime)); stopTimes.add(new StopTime(to, tripArrivalTime, tripArrivalTime)); Trip trip = new Trip(to.getName(), route, stopTimes); - return new Leg(from.getCoordinates(), to.getCoordinates(), from, to, LegType.ROUTE, departureTime, + return new Leg(from.getCoordinates(), to.getCoordinates(), from, to, LegType.ROUTE, tripDepartureTime, tripArrivalTime, trip); } public static List getDepartures(String stopId, LocalDateTime departureTime, int limit, LocalDateTime untilDateTime) { + logger.info("Getting departures for stop: " + stopId + " at " + departureTime + " with limit " + limit); + Stop stop = getStop(stopId); if (departureTime == null) { @@ -260,8 +272,7 @@ public static List getDepartures(String stopId, LocalDateTime departu continue; } - int randomMinutes = (int) (Math.random() * 120); - LocalDateTime tripDepartureTime = departureTime.plusMinutes(randomMinutes); + LocalDateTime tripDepartureTime = departureTime.plusMinutes(random.nextInt(120)); Leg leg = buildTripDummyLeg(stop, targetStop, tripDepartureTime); Trip trip = leg.getTrip(); @@ -286,6 +297,8 @@ public static List getConnections(String fromStopId, String toStopId Stop from = getStop(fromStopId); Stop to = getStop(toStopId); + logger.info("Getting connections from " + from.getName() + " to " + to.getName() + " at " + departureTime); + if (departureTime == null) { departureTime = LocalDateTime.now(); } diff --git a/src/main/java/ch/naviqore/api/controller/ScheduleController.java b/src/main/java/ch/naviqore/api/controller/ScheduleController.java index 80ab7318..45e70876 100644 --- a/src/main/java/ch/naviqore/api/controller/ScheduleController.java +++ b/src/main/java/ch/naviqore/api/controller/ScheduleController.java @@ -34,10 +34,10 @@ public Stop getStop(@PathVariable String stopId) { @GetMapping("/stops/{stopId}/departures") public List getDepartures(@PathVariable String stopId, - @RequestParam(required = false) LocalDateTime departureTime, + @RequestParam(required = false) LocalDateTime departureDateTime, @RequestParam(required = false, defaultValue = "10") int limit, @RequestParam(required = false) LocalDateTime untilDateTime) { - return DummyData.getDepartures(stopId, departureTime, limit, untilDateTime); + return DummyData.getDepartures(stopId, departureDateTime, limit, untilDateTime); } } diff --git a/src/main/resources/api/openapi.yaml b/src/main/resources/api/openapi.yaml index 0ce5b572..6b79a593 100644 --- a/src/main/resources/api/openapi.yaml +++ b/src/main/resources/api/openapi.yaml @@ -49,7 +49,7 @@ paths: schema: type: string description: The ID of the stop. - - name: dateTime + - name: departureDateTime in: query schema: type: string From ded19f105e3a38e1a1dcbbbbfbfc598966f5d405 Mon Sep 17 00:00:00 2001 From: Lukas Connolly Date: Sun, 26 May 2024 22:19:39 +0200 Subject: [PATCH 08/11] ENH: NAV-16 - Add more randomness and more stops for isoline generator. --- .../ch/naviqore/api/controller/DummyData.java | 144 +++++++++++++++--- 1 file changed, 119 insertions(+), 25 deletions(-) diff --git a/src/main/java/ch/naviqore/api/controller/DummyData.java b/src/main/java/ch/naviqore/api/controller/DummyData.java index 21d8b638..7dd34c01 100644 --- a/src/main/java/ch/naviqore/api/controller/DummyData.java +++ b/src/main/java/ch/naviqore/api/controller/DummyData.java @@ -1,20 +1,16 @@ package ch.naviqore.api.controller; import ch.naviqore.api.model.*; - -import java.time.LocalDateTime; -import java.util.ArrayList; -import java.util.Comparator; -import java.util.List; -import java.util.Random; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.time.LocalDateTime; +import java.util.*; + public class DummyData { - static Random random = new Random(); private static final Logger logger = LoggerFactory.getLogger(DummyData.class); + static Random random = new Random(); public static List getStops() { List dtos = new ArrayList<>(); @@ -41,6 +37,34 @@ public static List getStops() { dtos.add(new Stop("Stop-21", "Elsau, Melcher", new Coordinate(47.50171676, 8.787230279))); dtos.add(new Stop("Stop-22", "Wetzikon ZH, Walfershausen", new Coordinate(47.32205504, 8.797336326))); dtos.add(new Stop("Stop-23", "Hombrechtikon, Tobel", new Coordinate(47.25379065, 8.780986988))); + dtos.add(new Stop("Stop-24", "Mönchaltorf, Langenmatt", new Coordinate(47.315526886, 8.7209782185))); + dtos.add(new Stop("Stop-25", "Hinwil, Girenbad", new Coordinate(47.30950315, 8.87194141))); + dtos.add(new Stop("Stop-26", "Zürich, Polyterrasse ETH", new Coordinate(47.37685009, 8.546391951))); + dtos.add(new Stop("Stop-27", "Pfäffikon ZH, Humbel", new Coordinate(47.38172856, 8.800857722))); + dtos.add(new Stop("Stop-28", "Benken ZH, Dorf", new Coordinate(47.6529254, 8.653300453))); + dtos.add(new Stop("Stop-29", "Winkel, Oberrüti", new Coordinate(47.47994371, 8.563073666))); + dtos.add(new Stop("Stop-30", "Flaach, Wesenplatz", new Coordinate(47.57530917, 8.609651314))); + dtos.add(new Stop("Stop-31", "Laupen ZH, Schulhaus", new Coordinate(47.26536213, 8.929370706))); + dtos.add(new Stop("Stop-32", "Embrach, Dreispitz", new Coordinate(47.50995745, 8.593858931))); + dtos.add(new Stop("Stop-33", "Brütten, Zentrum", new Coordinate(47.47198977, 8.676189527))); + dtos.add(new Stop("Stop-34", "Mettmenstetten, Bahnhof", new Coordinate(47.24308265, 8.458671464))); + dtos.add(new Stop("Stop-35", "Baar, Bahnmatt", new Coordinate(47.19659729, 8.523862204))); + dtos.add(new Stop("Stop-36", "Rümlang, Bahnhof", new Coordinate(47.45400701, 8.532611795))); + dtos.add(new Stop("Stop-37", "Bachs, Weiherbach", new Coordinate(47.5193738, 8.44891576))); + dtos.add(new Stop("Stop-38", "Dachsen, Lindenstrasse", new Coordinate(47.66353213, 8.620538895))); + dtos.add(new Stop("Stop-39", "Russikon, Kirche", new Coordinate(47.39620313, 8.773108763))); + dtos.add(new Stop("Stop-40", "Weisslingen, Widum", new Coordinate(47.43468736, 8.76346984))); + dtos.add(new Stop("Stop-41", "Horgen, Stocker", new Coordinate(47.26150932, 8.58926854))); + dtos.add(new Stop("Stop-42", "Hirzel, Strickler", new Coordinate(47.22884668, 8.601844954))); + dtos.add(new Stop("Stop-43", "Sitzberg, Sternen", new Coordinate(47.4234933, 8.912563227))); + dtos.add(new Stop("Stop-44", "Buch am Irchel, Unterbuch", new Coordinate(47.54997739, 8.61878718))); + dtos.add(new Stop("Stop-45", "Oetwil am See, Bergstrasse", new Coordinate(47.26976326, 8.718051019))); + dtos.add(new Stop("Stop-46", "Pfungen, Eskimo", new Coordinate(47.51937987, 8.637202643))); + dtos.add(new Stop("Stop-47", "Wallisellen, Bahnhof", new Coordinate(47.41268592, 8.592933666))); + dtos.add(new Stop("Stop-48", "Maur, See", new Coordinate(47.33994896, 8.677968191))); + dtos.add(new Stop("Stop-49", "Meilen, Friedhof", new Coordinate(47.27177473, 8.641424725))); + dtos.add(new Stop("Stop-50", "Stäfa, Schützenhaus Wanne", new Coordinate(47.25471134, 8.720611217))); + return dtos; } @@ -88,7 +112,11 @@ public static List searchStops(String query, int limit, SearchType type) { } public static List getNearestStops(double latitude, double longitude, int maxDistance, int limit) { - List stops = getStops(); + return getNearestStops(getStops(), latitude, longitude, maxDistance, limit); + } + + private static List getNearestStops(List stops, double latitude, double longitude, + int maxDistance, int limit) { List result = new ArrayList<>(); for (Stop stop : stops) { double distance = approximateDistance(stop.getCoordinates(), new Coordinate(latitude, longitude)); @@ -182,19 +210,22 @@ private static Connection buildThreeLegDummyConnectionWithFootpath(Stop from, St ArrayList legs = new ArrayList<>(); Leg leg1 = buildTripDummyLeg(from, stopBetween, departureTime); legs.add(leg1); - - int footpathDistance = (int) approximateDistance(stopBetween.getCoordinates(), closestStop.getCoordinates()); - int footpathSpeed = 100; // meters per minute - int footpathTravelTime = footpathDistance / footpathSpeed; // in minutes - - Leg leg2 = new Leg(stopBetween.getCoordinates(), closestStop.getCoordinates(), stopBetween, closestStop, - LegType.WALK, leg1.getArrivalTime(), leg1.getArrivalTime().plusMinutes(footpathTravelTime), null); + Leg leg2 = buildFootpathLeg(stopBetween, closestStop, leg1.getArrivalTime()); legs.add(leg2); legs.add(buildTripDummyLeg(closestStop, to, leg2.getArrivalTime())); return new Connection(legs); } + private static Leg buildFootpathLeg(Stop from, Stop to, LocalDateTime departureTime) { + int footpathDistance = (int) approximateDistance(from.getCoordinates(), to.getCoordinates()); + int footpathSpeed = 100; // meters per minute + int footpathTravelTime = footpathDistance / footpathSpeed; // in minutes + + return new Leg(from.getCoordinates(), to.getCoordinates(), from, to, LegType.WALK, departureTime, + departureTime.plusMinutes(footpathTravelTime), null); + } + private static Stop getStopInBetweenStops(Stop from, Stop to, int randomness) { return getStopInBetweenStops(from, to, randomness, List.of(from, to)); } @@ -207,7 +238,7 @@ private static Stop getStopInBetweenStops(Stop from, Stop to, int randomness, Li Coordinate center = new Coordinate(centerLat, centerLon); List closestStops = getNearestStops(center.getLatitude(), center.getLongitude(), - Integer.MAX_VALUE, 3+randomness); + Integer.MAX_VALUE, 3 + randomness); // random sort to get different results closestStops.sort((a, b) -> { @@ -313,6 +344,9 @@ public static List getConnections(String fromStopId, String toStopId public static List getIsolines(String fromStopId, LocalDateTime departureTime, int maxTravelTime) { Stop from = getStop(fromStopId); + if (from == null) { + throw new IllegalArgumentException("Stop not found"); + } if (departureTime == null) { departureTime = LocalDateTime.now(); } @@ -323,20 +357,80 @@ public static List getIsolines(String fromStopId, LocalDateTime } List stops = getStops(); + List spawnStops = new ArrayList<>(); + stops.remove(from); + List isolines = new ArrayList<>(); + HashMap earliestArrivals = new HashMap<>(); + + // find nearest stop and walk there by foot + List closestStops = getNearestStops(from.getCoordinates().getLatitude(), + from.getCoordinates().getLongitude(), Integer.MAX_VALUE, 10); + Stop nearestStop = closestStops.get(0).getStop(); + spawnStops.add(nearestStop); + stops.remove(nearestStop); + earliestArrivals.put(nearestStop, buildFootpathLeg(from, nearestStop, departureTime)); + + // pick 3 random stops to add trip to + for (int i = 0; i < 3; i++) { + int randomIndex = random.nextInt(closestStops.size()); + DistanceToStop targetStopDistance = closestStops.get(randomIndex); + Stop targetStop = targetStopDistance.getStop(); + stops.remove(targetStop); + spawnStops.add(targetStop); + earliestArrivals.put(targetStop, buildTripDummyLeg(from, targetStop, departureTime)); + } - for (Stop targetStop : stops) { - if (from == targetStop) { - continue; + while (!stops.isEmpty()) { + Stop spawnStop; + if (spawnStops.isEmpty()) { + spawnStop = from; + } else { + spawnStop = spawnStops.removeFirst(); } - Connection connection = buildSimpleDummyConnection(from, targetStop, departureTime); + int maxConnections = stops.size() / 3; + int numConnections = random.nextInt(maxConnections + 2); - Leg lastLeg = connection.getLegs().get(connection.getLegs().size() - 1); - if (untilDateTime != null && lastLeg.getArrivalTime().isAfter(untilDateTime)) { - continue; + List nearestStops = getNearestStops(stops, spawnStop.getCoordinates().getLatitude(), + spawnStop.getCoordinates().getLongitude(), Integer.MAX_VALUE, 5 + numConnections); + + // shuffle to get not only closest stops + nearestStops.sort((a, b) -> { + if (a.getStop().equals(b.getStop()) && a.getDistance() == b.getDistance()) { + return 0; + } + return random.nextInt(3) < 2 ? -1 : 1; + }); + + LocalDateTime spawnDepartureTime = earliestArrivals.get(spawnStop).getArrivalTime(); + + for (int i = 0; i < numConnections; i++) { + Stop targetStop = nearestStops.get(i).getStop(); + stops.remove(targetStop); + spawnStops.add(targetStop); + Leg leg = buildTripDummyLeg(spawnStop, targetStop, spawnDepartureTime); + if (untilDateTime != null && leg.getArrivalTime().isAfter(untilDateTime)) { + continue; + } + earliestArrivals.put(targetStop, leg); + } + + } + + // build connections for all stops + for (Map.Entry entry : earliestArrivals.entrySet()) { + Stop targetStop = entry.getKey(); + Leg lastLeg = entry.getValue(); + List legs = new ArrayList<>(List.of(lastLeg)); + + while (lastLeg.getFromStop() != from) { + lastLeg = earliestArrivals.get(lastLeg.getFromStop()); + legs.add(lastLeg); } - isolines.add(new EarliestArrival(targetStop, lastLeg.getArrivalTime(), connection)); + // sort legs by departure time + legs.sort(Comparator.comparing(Leg::getDepartureTime)); + isolines.add(new EarliestArrival(targetStop, legs.getLast().getArrivalTime(), new Connection(legs))); } return isolines; From d5bcb17dd6293a9649517c8b2ce3a4a710e10eaf Mon Sep 17 00:00:00 2001 From: Lukas Connolly Date: Sun, 26 May 2024 22:37:05 +0200 Subject: [PATCH 09/11] REFACTOR: NAV-16 - Minor cleanup and tuning of generator parameters. --- .../java/ch/naviqore/api/controller/DummyData.java | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/main/java/ch/naviqore/api/controller/DummyData.java b/src/main/java/ch/naviqore/api/controller/DummyData.java index 7dd34c01..4df027f1 100644 --- a/src/main/java/ch/naviqore/api/controller/DummyData.java +++ b/src/main/java/ch/naviqore/api/controller/DummyData.java @@ -364,9 +364,9 @@ public static List getIsolines(String fromStopId, LocalDateTime HashMap earliestArrivals = new HashMap<>(); // find nearest stop and walk there by foot - List closestStops = getNearestStops(from.getCoordinates().getLatitude(), + List closestStops = getNearestStops(stops, from.getCoordinates().getLatitude(), from.getCoordinates().getLongitude(), Integer.MAX_VALUE, 10); - Stop nearestStop = closestStops.get(0).getStop(); + Stop nearestStop = closestStops.getFirst().getStop(); spawnStops.add(nearestStop); stops.remove(nearestStop); earliestArrivals.put(nearestStop, buildFootpathLeg(from, nearestStop, departureTime)); @@ -388,8 +388,11 @@ public static List getIsolines(String fromStopId, LocalDateTime } else { spawnStop = spawnStops.removeFirst(); } - int maxConnections = stops.size() / 3; - int numConnections = random.nextInt(maxConnections + 2); + int maxConnections = stops.size() / 4; + if (maxConnections < 2) { + maxConnections = 2; + } + int numConnections = random.nextInt(maxConnections); List nearestStops = getNearestStops(stops, spawnStop.getCoordinates().getLatitude(), spawnStop.getCoordinates().getLongitude(), Integer.MAX_VALUE, 5 + numConnections); From d9476757e8861448b2046e643f6412689190e208 Mon Sep 17 00:00:00 2001 From: Merlin Unterfinger Date: Mon, 27 May 2024 00:05:13 +0200 Subject: [PATCH 10/11] REFACTOR: NAV-16 - Refactoring suggestions - Avoid boiler plate code, use lombok instead. - Add REST test file. - Rename api to app package, due to architectural overview. --- .../ch/naviqore/api/model/Connection.java | 58 ----------- .../ch/naviqore/api/model/Coordinate.java | 63 ------------ .../java/ch/naviqore/api/model/Departure.java | 62 ------------ .../ch/naviqore/api/model/DistanceToStop.java | 62 ------------ .../naviqore/api/model/EarliestArrival.java | 71 ------------- src/main/java/ch/naviqore/api/model/Leg.java | 99 ------------------- .../java/ch/naviqore/api/model/LegType.java | 42 -------- .../java/ch/naviqore/api/model/Route.java | 74 -------------- .../ch/naviqore/api/model/SearchType.java | 48 --------- src/main/java/ch/naviqore/api/model/Stop.java | 69 ------------- .../java/ch/naviqore/api/model/StopTime.java | 77 --------------- src/main/java/ch/naviqore/api/model/Trip.java | 69 ------------- .../ch/naviqore/{api => app}/Application.java | 2 +- .../{api => app}/controller/DummyData.java | 4 +- .../controller/RoutingController.java | 6 +- .../controller/ScheduleController.java | 10 +- .../ch/naviqore/app/model/Connection.java | 19 ++++ .../ch/naviqore/app/model/Coordinate.java | 18 ++++ .../java/ch/naviqore/app/model/Departure.java | 18 ++++ .../ch/naviqore/app/model/DistanceToStop.java | 18 ++++ .../naviqore/app/model/EarliestArrival.java | 23 +++++ src/main/java/ch/naviqore/app/model/Leg.java | 29 ++++++ .../java/ch/naviqore/app/model/LegType.java | 33 +++++++ .../java/ch/naviqore/app/model/Route.java | 20 ++++ .../ch/naviqore/app/model/SearchType.java | 35 +++++++ src/main/java/ch/naviqore/app/model/Stop.java | 19 ++++ .../java/ch/naviqore/app/model/StopTime.java | 24 +++++ src/main/java/ch/naviqore/app/model/Trip.java | 21 ++++ src/main/resources/api/openapi.yaml | 18 ++-- .../schedule/type/ServiceDayTimeTest.java | 6 +- .../ch/naviqore/app/ApplicationTest.rest | 19 ++++ 31 files changed, 320 insertions(+), 816 deletions(-) delete mode 100644 src/main/java/ch/naviqore/api/model/Connection.java delete mode 100644 src/main/java/ch/naviqore/api/model/Coordinate.java delete mode 100644 src/main/java/ch/naviqore/api/model/Departure.java delete mode 100644 src/main/java/ch/naviqore/api/model/DistanceToStop.java delete mode 100644 src/main/java/ch/naviqore/api/model/EarliestArrival.java delete mode 100644 src/main/java/ch/naviqore/api/model/Leg.java delete mode 100644 src/main/java/ch/naviqore/api/model/LegType.java delete mode 100644 src/main/java/ch/naviqore/api/model/Route.java delete mode 100644 src/main/java/ch/naviqore/api/model/SearchType.java delete mode 100644 src/main/java/ch/naviqore/api/model/Stop.java delete mode 100644 src/main/java/ch/naviqore/api/model/StopTime.java delete mode 100644 src/main/java/ch/naviqore/api/model/Trip.java rename src/main/java/ch/naviqore/{api => app}/Application.java (91%) rename src/main/java/ch/naviqore/{api => app}/controller/DummyData.java (99%) rename src/main/java/ch/naviqore/{api => app}/controller/RoutingController.java (94%) rename src/main/java/ch/naviqore/{api => app}/controller/ScheduleController.java (89%) create mode 100644 src/main/java/ch/naviqore/app/model/Connection.java create mode 100644 src/main/java/ch/naviqore/app/model/Coordinate.java create mode 100644 src/main/java/ch/naviqore/app/model/Departure.java create mode 100644 src/main/java/ch/naviqore/app/model/DistanceToStop.java create mode 100644 src/main/java/ch/naviqore/app/model/EarliestArrival.java create mode 100644 src/main/java/ch/naviqore/app/model/Leg.java create mode 100644 src/main/java/ch/naviqore/app/model/LegType.java create mode 100644 src/main/java/ch/naviqore/app/model/Route.java create mode 100644 src/main/java/ch/naviqore/app/model/SearchType.java create mode 100644 src/main/java/ch/naviqore/app/model/Stop.java create mode 100644 src/main/java/ch/naviqore/app/model/StopTime.java create mode 100644 src/main/java/ch/naviqore/app/model/Trip.java create mode 100644 src/test/resources/ch/naviqore/app/ApplicationTest.rest diff --git a/src/main/java/ch/naviqore/api/model/Connection.java b/src/main/java/ch/naviqore/api/model/Connection.java deleted file mode 100644 index cc452129..00000000 --- a/src/main/java/ch/naviqore/api/model/Connection.java +++ /dev/null @@ -1,58 +0,0 @@ -package ch.naviqore.api.model; - -import com.fasterxml.jackson.annotation.JsonProperty; -import lombok.Getter; - -import java.util.List; -import java.util.Objects; - -/** - * Connection - */ -@Getter -public class Connection { - - @JsonProperty("legs") - private List legs; - - public Connection(List legs) { - this.legs = legs; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - Connection connection = (Connection) o; - return Objects.equals(this.legs, connection.legs); - } - - @Override - public int hashCode() { - return Objects.hash(legs); - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("class Connection {\n"); - sb.append(" legs: ").append(toIndentedString(legs)).append("\n"); - sb.append("}"); - return sb.toString(); - } - - /** - * Convert the given object to string with each line indented by 4 spaces (except the first line). - */ - private String toIndentedString(Object o) { - if (o == null) { - return "null"; - } - return o.toString().replace("\n", "\n "); - } -} - diff --git a/src/main/java/ch/naviqore/api/model/Coordinate.java b/src/main/java/ch/naviqore/api/model/Coordinate.java deleted file mode 100644 index 4c7f0756..00000000 --- a/src/main/java/ch/naviqore/api/model/Coordinate.java +++ /dev/null @@ -1,63 +0,0 @@ -package ch.naviqore.api.model; - -import com.fasterxml.jackson.annotation.JsonProperty; -import lombok.Getter; - -import java.util.Objects; - -/** - * Coordinate - */ -@Getter -public class Coordinate { - - @JsonProperty("latitude") - private double latitude; - - @JsonProperty("longitude") - private double longitude; - - public Coordinate(double latitude, double longitude) { - this.latitude = latitude; - this.longitude = longitude; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - Coordinate coordinate = (Coordinate) o; - return Objects.equals(this.latitude, coordinate.latitude) && Objects.equals(this.longitude, - coordinate.longitude); - } - - @Override - public int hashCode() { - return Objects.hash(latitude, longitude); - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("class Coordinate {\n"); - sb.append(" latitude: ").append(toIndentedString(latitude)).append("\n"); - sb.append(" longitude: ").append(toIndentedString(longitude)).append("\n"); - sb.append("}"); - return sb.toString(); - } - - /** - * Convert the given object to string with each line indented by 4 spaces (except the first line). - */ - private String toIndentedString(Object o) { - if (o == null) { - return "null"; - } - return o.toString().replace("\n", "\n "); - } -} - diff --git a/src/main/java/ch/naviqore/api/model/Departure.java b/src/main/java/ch/naviqore/api/model/Departure.java deleted file mode 100644 index 73ea33e4..00000000 --- a/src/main/java/ch/naviqore/api/model/Departure.java +++ /dev/null @@ -1,62 +0,0 @@ -package ch.naviqore.api.model; - -import com.fasterxml.jackson.annotation.JsonProperty; -import lombok.Getter; - -import java.util.Objects; - -/** - * Departure - */ -@Getter -public class Departure { - - @JsonProperty("stopTime") - private StopTime stopTime; - - @JsonProperty("trip") - private Trip trip; - - public Departure(StopTime stopTime, Trip trip) { - this.stopTime = stopTime; - this.trip = trip; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - Departure departure = (Departure) o; - return Objects.equals(this.stopTime, departure.stopTime) && Objects.equals(this.trip, departure.trip); - } - - @Override - public int hashCode() { - return Objects.hash(stopTime, trip); - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("class Departure {\n"); - sb.append(" stopTime: ").append(toIndentedString(stopTime)).append("\n"); - sb.append(" trip: ").append(toIndentedString(trip)).append("\n"); - sb.append("}"); - return sb.toString(); - } - - /** - * Convert the given object to string with each line indented by 4 spaces (except the first line). - */ - private String toIndentedString(Object o) { - if (o == null) { - return "null"; - } - return o.toString().replace("\n", "\n "); - } -} - diff --git a/src/main/java/ch/naviqore/api/model/DistanceToStop.java b/src/main/java/ch/naviqore/api/model/DistanceToStop.java deleted file mode 100644 index 62600224..00000000 --- a/src/main/java/ch/naviqore/api/model/DistanceToStop.java +++ /dev/null @@ -1,62 +0,0 @@ -package ch.naviqore.api.model; - -import com.fasterxml.jackson.annotation.JsonProperty; -import lombok.Getter; - -import java.util.Objects; - -/** - * DistanceToStop - */ -@Getter -public class DistanceToStop { - - @JsonProperty("stop") - private Stop stop; - - @JsonProperty("distance") - private double distance; - - public DistanceToStop(Stop stop, double distance) { - this.stop = stop; - this.distance = distance; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - DistanceToStop distanceToStop = (DistanceToStop) o; - return Objects.equals(this.stop, distanceToStop.stop) && Objects.equals(this.distance, distanceToStop.distance); - } - - @Override - public int hashCode() { - return Objects.hash(stop, distance); - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("class DistanceToStop {\n"); - sb.append(" stop: ").append(toIndentedString(stop)).append("\n"); - sb.append(" distance: ").append(toIndentedString(distance)).append("\n"); - sb.append("}"); - return sb.toString(); - } - - /** - * Convert the given object to string with each line indented by 4 spaces (except the first line). - */ - private String toIndentedString(Object o) { - if (o == null) { - return "null"; - } - return o.toString().replace("\n", "\n "); - } -} - diff --git a/src/main/java/ch/naviqore/api/model/EarliestArrival.java b/src/main/java/ch/naviqore/api/model/EarliestArrival.java deleted file mode 100644 index 510741d7..00000000 --- a/src/main/java/ch/naviqore/api/model/EarliestArrival.java +++ /dev/null @@ -1,71 +0,0 @@ -package ch.naviqore.api.model; - -import com.fasterxml.jackson.annotation.JsonProperty; -import lombok.Getter; -import org.springframework.format.annotation.DateTimeFormat; - -import java.time.LocalDateTime; -import java.util.Objects; - -/** - * EarliestArrival - */ -@Getter -public class EarliestArrival { - - @JsonProperty("stop") - private Stop stop; - - @JsonProperty("arrivalTime") - @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) - private LocalDateTime arrivalTime; - - @JsonProperty("connection") - private Connection connection; - - public EarliestArrival(Stop stop, LocalDateTime arrivalTime, Connection connection) { - this.stop = stop; - this.arrivalTime = arrivalTime; - this.connection = connection; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - EarliestArrival earliestArrival = (EarliestArrival) o; - return Objects.equals(this.stop, earliestArrival.stop) && Objects.equals(this.arrivalTime, - earliestArrival.arrivalTime) && Objects.equals(this.connection, earliestArrival.connection); - } - - @Override - public int hashCode() { - return Objects.hash(stop, arrivalTime, connection); - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("class EarliestArrival {\n"); - sb.append(" stop: ").append(toIndentedString(stop)).append("\n"); - sb.append(" arrivalTime: ").append(toIndentedString(arrivalTime)).append("\n"); - sb.append(" connection: ").append(toIndentedString(connection)).append("\n"); - sb.append("}"); - return sb.toString(); - } - - /** - * Convert the given object to string with each line indented by 4 spaces (except the first line). - */ - private String toIndentedString(Object o) { - if (o == null) { - return "null"; - } - return o.toString().replace("\n", "\n "); - } -} - diff --git a/src/main/java/ch/naviqore/api/model/Leg.java b/src/main/java/ch/naviqore/api/model/Leg.java deleted file mode 100644 index 0e7cbb08..00000000 --- a/src/main/java/ch/naviqore/api/model/Leg.java +++ /dev/null @@ -1,99 +0,0 @@ -package ch.naviqore.api.model; - -import com.fasterxml.jackson.annotation.JsonProperty; -import lombok.Getter; -import org.springframework.format.annotation.DateTimeFormat; - -import java.time.LocalDateTime; -import java.util.Objects; - -/** - * Leg - */ -@Getter -public class Leg { - - @JsonProperty("from") - private Coordinate from; - - @JsonProperty("to") - private Coordinate to; - - @JsonProperty("fromStop") - private Stop fromStop; - - @JsonProperty("toStop") - private Stop toStop; - - @JsonProperty("type") - private LegType type; - - @JsonProperty("departureTime") - @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) - private LocalDateTime departureTime; - - @JsonProperty("arrivalTime") - @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) - private LocalDateTime arrivalTime; - - @JsonProperty("trip") - private Trip trip; - - public Leg(Coordinate from, Coordinate to, Stop fromStop, Stop toStop, LegType type, LocalDateTime departureTime, - LocalDateTime arrivalTime, Trip trip) { - this.from = from; - this.to = to; - this.fromStop = fromStop; - this.toStop = toStop; - this.type = type; - this.departureTime = departureTime; - this.arrivalTime = arrivalTime; - this.trip = trip; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - Leg leg = (Leg) o; - return Objects.equals(this.from, leg.from) && Objects.equals(this.to, leg.to) && Objects.equals(this.fromStop, - leg.fromStop) && Objects.equals(this.toStop, leg.toStop) && Objects.equals(this.type, - leg.type) && Objects.equals(this.departureTime, leg.departureTime) && Objects.equals(this.arrivalTime, - leg.arrivalTime); - } - - @Override - public int hashCode() { - return Objects.hash(from, to, fromStop, toStop, type, departureTime, arrivalTime); - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("class Leg {\n"); - sb.append(" from: ").append(toIndentedString(from)).append("\n"); - sb.append(" to: ").append(toIndentedString(to)).append("\n"); - sb.append(" fromStop: ").append(toIndentedString(fromStop)).append("\n"); - sb.append(" toStop: ").append(toIndentedString(toStop)).append("\n"); - sb.append(" type: ").append(toIndentedString(type)).append("\n"); - sb.append(" departureTime: ").append(toIndentedString(departureTime)).append("\n"); - sb.append(" arrivalTime: ").append(toIndentedString(arrivalTime)).append("\n"); - sb.append("}"); - return sb.toString(); - } - - /** - * Convert the given object to string with each line indented by 4 spaces (except the first line). - */ - private String toIndentedString(Object o) { - if (o == null) { - return "null"; - } - return o.toString().replace("\n", "\n "); - } -} - diff --git a/src/main/java/ch/naviqore/api/model/LegType.java b/src/main/java/ch/naviqore/api/model/LegType.java deleted file mode 100644 index 54a41fc2..00000000 --- a/src/main/java/ch/naviqore/api/model/LegType.java +++ /dev/null @@ -1,42 +0,0 @@ -package ch.naviqore.api.model; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonValue; - -/** - * Gets or Sets LegType - */ - -public enum LegType { - - WALK("WALK"), - - ROUTE("ROUTE"); - - private final String value; - - LegType(String value) { - this.value = value; - } - - @JsonValue - public String getValue() { - return value; - } - - @Override - public String toString() { - return String.valueOf(value); - } - - @JsonCreator - public static LegType fromValue(String value) { - for (LegType b : LegType.values()) { - if (b.value.equals(value)) { - return b; - } - } - throw new IllegalArgumentException("Unexpected value '" + value + "'"); - } -} - diff --git a/src/main/java/ch/naviqore/api/model/Route.java b/src/main/java/ch/naviqore/api/model/Route.java deleted file mode 100644 index 33559653..00000000 --- a/src/main/java/ch/naviqore/api/model/Route.java +++ /dev/null @@ -1,74 +0,0 @@ -package ch.naviqore.api.model; - -import com.fasterxml.jackson.annotation.JsonProperty; -import lombok.Getter; - -import java.util.Objects; - -/** - * Route - */ - -@Getter -public class Route { - - @JsonProperty("id") - private String id; - - @JsonProperty("name") - private String name; - - @JsonProperty("shortName") - private String shortName; - - @JsonProperty("transportMode") - private String transportMode; - - public Route(String id, String name, String shortName, String transportMode) { - this.id = id; - this.name = name; - this.shortName = shortName; - this.transportMode = transportMode; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - Route route = (Route) o; - return Objects.equals(this.id, route.id) && Objects.equals(this.name, route.name) && Objects.equals( - this.shortName, route.shortName) && Objects.equals(this.transportMode, route.transportMode); - } - - @Override - public int hashCode() { - return Objects.hash(id, name, shortName, transportMode); - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("class Route {\n"); - sb.append(" id: ").append(toIndentedString(id)).append("\n"); - sb.append(" name: ").append(toIndentedString(name)).append("\n"); - sb.append(" shortName: ").append(toIndentedString(shortName)).append("\n"); - sb.append(" transportMode: ").append(toIndentedString(transportMode)).append("\n"); - sb.append("}"); - return sb.toString(); - } - - /** - * Convert the given object to string with each line indented by 4 spaces (except the first line). - */ - private String toIndentedString(Object o) { - if (o == null) { - return "null"; - } - return o.toString().replace("\n", "\n "); - } -} - diff --git a/src/main/java/ch/naviqore/api/model/SearchType.java b/src/main/java/ch/naviqore/api/model/SearchType.java deleted file mode 100644 index 7a144644..00000000 --- a/src/main/java/ch/naviqore/api/model/SearchType.java +++ /dev/null @@ -1,48 +0,0 @@ -package ch.naviqore.api.model; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonValue; - -/** - * Gets or Sets SearchType - */ - -public enum SearchType { - - EXACT("EXACT"), - - STARTS_WITH("STARTS_WITH"), - - CONTAINS("CONTAINS"), - - ENDS_WITH("ENDS_WITH"), - - FUZZY("FUZZY"); - - private final String value; - - SearchType(String value) { - this.value = value; - } - - @JsonValue - public String getValue() { - return value; - } - - @Override - public String toString() { - return String.valueOf(value); - } - - @JsonCreator - public static SearchType fromValue(String value) { - for (SearchType b : SearchType.values()) { - if (b.value.equals(value)) { - return b; - } - } - throw new IllegalArgumentException("Unexpected value '" + value + "'"); - } -} - diff --git a/src/main/java/ch/naviqore/api/model/Stop.java b/src/main/java/ch/naviqore/api/model/Stop.java deleted file mode 100644 index 63f425cc..00000000 --- a/src/main/java/ch/naviqore/api/model/Stop.java +++ /dev/null @@ -1,69 +0,0 @@ -package ch.naviqore.api.model; - -import com.fasterxml.jackson.annotation.JsonProperty; -import lombok.Getter; - -import java.util.Objects; - -/** - * Stop - */ - -@Getter -public class Stop { - - @JsonProperty("id") - private String id; - - @JsonProperty("name") - private String name; - - @JsonProperty("coordinates") - private Coordinate coordinates; - - public Stop(String id, String name, Coordinate coordinates) { - this.id = id; - this.name = name; - this.coordinates = coordinates; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - Stop stop = (Stop) o; - return Objects.equals(this.id, stop.id) && Objects.equals(this.name, stop.name) && Objects.equals( - this.coordinates, stop.coordinates); - } - - @Override - public int hashCode() { - return Objects.hash(id, name, coordinates); - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("class Stop {\n"); - sb.append(" id: ").append(toIndentedString(id)).append("\n"); - sb.append(" name: ").append(toIndentedString(name)).append("\n"); - sb.append(" coordinates: ").append(toIndentedString(coordinates)).append("\n"); - sb.append("}"); - return sb.toString(); - } - - /** - * Convert the given object to string with each line indented by 4 spaces (except the first line). - */ - private String toIndentedString(Object o) { - if (o == null) { - return "null"; - } - return o.toString().replace("\n", "\n "); - } -} - diff --git a/src/main/java/ch/naviqore/api/model/StopTime.java b/src/main/java/ch/naviqore/api/model/StopTime.java deleted file mode 100644 index 4ed4473e..00000000 --- a/src/main/java/ch/naviqore/api/model/StopTime.java +++ /dev/null @@ -1,77 +0,0 @@ -package ch.naviqore.api.model; - -import com.fasterxml.jackson.annotation.JsonProperty; -import lombok.Getter; -import org.springframework.format.annotation.DateTimeFormat; - -import java.time.LocalDateTime; -import java.util.Objects; - -/** - * StopTime - */ -@Getter -public class StopTime { - - @JsonProperty("stop") - private Stop stop; - - @JsonProperty("arrivalTime") - @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) - private LocalDateTime arrivalTime; - - @JsonProperty("departureTime") - @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) - private LocalDateTime departureTime; - - public StopTime(Stop stop, LocalDateTime arrivalTime, LocalDateTime departureTime) { - this.stop = stop; - this.arrivalTime = arrivalTime; - this.departureTime = departureTime; - } - - public StopTime stop(Stop stop) { - this.stop = stop; - return this; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - StopTime stopTime = (StopTime) o; - return Objects.equals(this.stop, stopTime.stop) && Objects.equals(this.arrivalTime, - stopTime.arrivalTime) && Objects.equals(this.departureTime, stopTime.departureTime); - } - - @Override - public int hashCode() { - return Objects.hash(stop, arrivalTime, departureTime); - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("class StopTime {\n"); - sb.append(" stop: ").append(toIndentedString(stop)).append("\n"); - sb.append(" arrivalTime: ").append(toIndentedString(arrivalTime)).append("\n"); - sb.append(" departureTime: ").append(toIndentedString(departureTime)).append("\n"); - sb.append("}"); - return sb.toString(); - } - - /** - * Convert the given object to string with each line indented by 4 spaces (except the first line). - */ - private String toIndentedString(Object o) { - if (o == null) { - return "null"; - } - return o.toString().replace("\n", "\n "); - } -} - diff --git a/src/main/java/ch/naviqore/api/model/Trip.java b/src/main/java/ch/naviqore/api/model/Trip.java deleted file mode 100644 index e874f1a7..00000000 --- a/src/main/java/ch/naviqore/api/model/Trip.java +++ /dev/null @@ -1,69 +0,0 @@ -package ch.naviqore.api.model; - -import com.fasterxml.jackson.annotation.JsonProperty; -import lombok.Getter; - -import java.util.List; -import java.util.Objects; - -/** - * Trip - */ -@Getter -public class Trip { - - @JsonProperty("headSign") - private String headSign; - - @JsonProperty("route") - private Route route; - - @JsonProperty("stopTimes") - private List stopTimes; - - public Trip(String headSign, Route route, List stopTimes) { - this.headSign = headSign; - this.route = route; - this.stopTimes = stopTimes; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - Trip trip = (Trip) o; - return Objects.equals(this.headSign, trip.headSign) && Objects.equals(this.route, trip.route) && Objects.equals( - this.stopTimes, trip.stopTimes); - } - - @Override - public int hashCode() { - return Objects.hash(headSign, route, stopTimes); - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("class Trip {\n"); - sb.append(" headSign: ").append(toIndentedString(headSign)).append("\n"); - sb.append(" route: ").append(toIndentedString(route)).append("\n"); - sb.append(" stopTimes: ").append(toIndentedString(stopTimes)).append("\n"); - sb.append("}"); - return sb.toString(); - } - - /** - * Convert the given object to string with each line indented by 4 spaces (except the first line). - */ - private String toIndentedString(Object o) { - if (o == null) { - return "null"; - } - return o.toString().replace("\n", "\n "); - } -} - diff --git a/src/main/java/ch/naviqore/api/Application.java b/src/main/java/ch/naviqore/app/Application.java similarity index 91% rename from src/main/java/ch/naviqore/api/Application.java rename to src/main/java/ch/naviqore/app/Application.java index fa4c0a14..985c4e61 100644 --- a/src/main/java/ch/naviqore/api/Application.java +++ b/src/main/java/ch/naviqore/app/Application.java @@ -1,4 +1,4 @@ -package ch.naviqore.api; +package ch.naviqore.app; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; diff --git a/src/main/java/ch/naviqore/api/controller/DummyData.java b/src/main/java/ch/naviqore/app/controller/DummyData.java similarity index 99% rename from src/main/java/ch/naviqore/api/controller/DummyData.java rename to src/main/java/ch/naviqore/app/controller/DummyData.java index 4df027f1..c330d165 100644 --- a/src/main/java/ch/naviqore/api/controller/DummyData.java +++ b/src/main/java/ch/naviqore/app/controller/DummyData.java @@ -1,6 +1,6 @@ -package ch.naviqore.api.controller; +package ch.naviqore.app.controller; -import ch.naviqore.api.model.*; +import ch.naviqore.app.model.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/src/main/java/ch/naviqore/api/controller/RoutingController.java b/src/main/java/ch/naviqore/app/controller/RoutingController.java similarity index 94% rename from src/main/java/ch/naviqore/api/controller/RoutingController.java rename to src/main/java/ch/naviqore/app/controller/RoutingController.java index 9a721dfc..922623ea 100644 --- a/src/main/java/ch/naviqore/api/controller/RoutingController.java +++ b/src/main/java/ch/naviqore/app/controller/RoutingController.java @@ -1,7 +1,7 @@ -package ch.naviqore.api.controller; +package ch.naviqore.app.controller; -import ch.naviqore.api.model.Connection; -import ch.naviqore.api.model.EarliestArrival; +import ch.naviqore.app.model.Connection; +import ch.naviqore.app.model.EarliestArrival; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; diff --git a/src/main/java/ch/naviqore/api/controller/ScheduleController.java b/src/main/java/ch/naviqore/app/controller/ScheduleController.java similarity index 89% rename from src/main/java/ch/naviqore/api/controller/ScheduleController.java rename to src/main/java/ch/naviqore/app/controller/ScheduleController.java index 45e70876..8ff1577f 100644 --- a/src/main/java/ch/naviqore/api/controller/ScheduleController.java +++ b/src/main/java/ch/naviqore/app/controller/ScheduleController.java @@ -1,9 +1,9 @@ -package ch.naviqore.api.controller; +package ch.naviqore.app.controller; -import ch.naviqore.api.model.Departure; -import ch.naviqore.api.model.DistanceToStop; -import ch.naviqore.api.model.SearchType; -import ch.naviqore.api.model.Stop; +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 org.springframework.web.bind.annotation.*; import java.time.LocalDateTime; diff --git a/src/main/java/ch/naviqore/app/model/Connection.java b/src/main/java/ch/naviqore/app/model/Connection.java new file mode 100644 index 00000000..abff876c --- /dev/null +++ b/src/main/java/ch/naviqore/app/model/Connection.java @@ -0,0 +1,19 @@ +package ch.naviqore.app.model; + +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import lombok.ToString; + +import java.util.List; + +@RequiredArgsConstructor +@EqualsAndHashCode +@ToString +@Getter +public class Connection { + + private final List legs; + +} + diff --git a/src/main/java/ch/naviqore/app/model/Coordinate.java b/src/main/java/ch/naviqore/app/model/Coordinate.java new file mode 100644 index 00000000..337d4fe6 --- /dev/null +++ b/src/main/java/ch/naviqore/app/model/Coordinate.java @@ -0,0 +1,18 @@ +package ch.naviqore.app.model; + +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import lombok.ToString; + +@RequiredArgsConstructor +@EqualsAndHashCode +@ToString +@Getter +public class Coordinate { + + private final double latitude; + private final double longitude; + +} + diff --git a/src/main/java/ch/naviqore/app/model/Departure.java b/src/main/java/ch/naviqore/app/model/Departure.java new file mode 100644 index 00000000..7b596727 --- /dev/null +++ b/src/main/java/ch/naviqore/app/model/Departure.java @@ -0,0 +1,18 @@ +package ch.naviqore.app.model; + +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import lombok.ToString; + +@RequiredArgsConstructor +@EqualsAndHashCode +@ToString +@Getter +public class Departure { + + private final StopTime stopTime; + private final Trip trip; + +} + diff --git a/src/main/java/ch/naviqore/app/model/DistanceToStop.java b/src/main/java/ch/naviqore/app/model/DistanceToStop.java new file mode 100644 index 00000000..c2c658e3 --- /dev/null +++ b/src/main/java/ch/naviqore/app/model/DistanceToStop.java @@ -0,0 +1,18 @@ +package ch.naviqore.app.model; + +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import lombok.ToString; + +@RequiredArgsConstructor +@EqualsAndHashCode +@ToString +@Getter +public class DistanceToStop { + + private final Stop stop; + private final double distance; + +} + diff --git a/src/main/java/ch/naviqore/app/model/EarliestArrival.java b/src/main/java/ch/naviqore/app/model/EarliestArrival.java new file mode 100644 index 00000000..a68466b2 --- /dev/null +++ b/src/main/java/ch/naviqore/app/model/EarliestArrival.java @@ -0,0 +1,23 @@ +package ch.naviqore.app.model; + +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import lombok.ToString; +import org.springframework.format.annotation.DateTimeFormat; + +import java.time.LocalDateTime; + +@RequiredArgsConstructor +@EqualsAndHashCode +@ToString +@Getter +public class EarliestArrival { + + private final Stop stop; + @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) + private final LocalDateTime arrivalTime; + private final Connection connection; + +} + diff --git a/src/main/java/ch/naviqore/app/model/Leg.java b/src/main/java/ch/naviqore/app/model/Leg.java new file mode 100644 index 00000000..a20b46a5 --- /dev/null +++ b/src/main/java/ch/naviqore/app/model/Leg.java @@ -0,0 +1,29 @@ +package ch.naviqore.app.model; + +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import lombok.ToString; +import org.springframework.format.annotation.DateTimeFormat; + +import java.time.LocalDateTime; + +@RequiredArgsConstructor +@EqualsAndHashCode +@ToString +@Getter +public class Leg { + + private final Coordinate from; + private final Coordinate to; + private final Stop fromStop; + private final Stop toStop; + private final LegType type; + @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) + private final LocalDateTime departureTime; + @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) + private final LocalDateTime arrivalTime; + private final Trip trip; + +} + diff --git a/src/main/java/ch/naviqore/app/model/LegType.java b/src/main/java/ch/naviqore/app/model/LegType.java new file mode 100644 index 00000000..5efa8900 --- /dev/null +++ b/src/main/java/ch/naviqore/app/model/LegType.java @@ -0,0 +1,33 @@ +package ch.naviqore.app.model; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; +import lombok.AccessLevel; +import lombok.RequiredArgsConstructor; +import lombok.ToString; + +@RequiredArgsConstructor(access = AccessLevel.PRIVATE) +@ToString +public enum LegType { + + WALK("WALK"), + ROUTE("ROUTE"); + + private final String value; + + @JsonCreator + public static LegType fromValue(String value) { + for (LegType b : LegType.values()) { + if (b.value.equals(value)) { + return b; + } + } + throw new IllegalArgumentException("Unexpected value '" + value + "'"); + } + + @JsonValue + public String getValue() { + return value; + } +} + diff --git a/src/main/java/ch/naviqore/app/model/Route.java b/src/main/java/ch/naviqore/app/model/Route.java new file mode 100644 index 00000000..e927c68b --- /dev/null +++ b/src/main/java/ch/naviqore/app/model/Route.java @@ -0,0 +1,20 @@ +package ch.naviqore.app.model; + +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import lombok.ToString; + +@RequiredArgsConstructor +@EqualsAndHashCode(of = "id") +@ToString +@Getter +public class Route { + + private final String id; + private final String name; + private final String shortName; + private final String transportMode; + +} + diff --git a/src/main/java/ch/naviqore/app/model/SearchType.java b/src/main/java/ch/naviqore/app/model/SearchType.java new file mode 100644 index 00000000..5ede1ec8 --- /dev/null +++ b/src/main/java/ch/naviqore/app/model/SearchType.java @@ -0,0 +1,35 @@ +package ch.naviqore.app.model; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; +import lombok.AccessLevel; +import lombok.RequiredArgsConstructor; + +@RequiredArgsConstructor(access = AccessLevel.PRIVATE) +public enum SearchType { + + EXACT("EXACT"), + STARTS_WITH("STARTS_WITH"), + CONTAINS("CONTAINS"), + ENDS_WITH("ENDS_WITH"), + FUZZY("FUZZY"); + + private final String value; + + @JsonCreator + public static SearchType fromValue(String value) { + for (SearchType b : SearchType.values()) { + if (b.value.equals(value)) { + return b; + } + } + throw new IllegalArgumentException("Unexpected value '" + value + "'"); + } + + @JsonValue + public String getValue() { + return value; + } + +} + diff --git a/src/main/java/ch/naviqore/app/model/Stop.java b/src/main/java/ch/naviqore/app/model/Stop.java new file mode 100644 index 00000000..d3ff1f04 --- /dev/null +++ b/src/main/java/ch/naviqore/app/model/Stop.java @@ -0,0 +1,19 @@ +package ch.naviqore.app.model; + +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import lombok.ToString; + +@RequiredArgsConstructor +@EqualsAndHashCode(of = "id") +@ToString +@Getter +public class Stop { + + private final String id; + private final String name; + private final Coordinate coordinates; + +} + diff --git a/src/main/java/ch/naviqore/app/model/StopTime.java b/src/main/java/ch/naviqore/app/model/StopTime.java new file mode 100644 index 00000000..08e75e9b --- /dev/null +++ b/src/main/java/ch/naviqore/app/model/StopTime.java @@ -0,0 +1,24 @@ +package ch.naviqore.app.model; + +import lombok.AllArgsConstructor; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.ToString; +import org.springframework.format.annotation.DateTimeFormat; + +import java.time.LocalDateTime; + +@AllArgsConstructor +@EqualsAndHashCode +@ToString +@Getter +public class StopTime { + + private Stop stop; + @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) + private LocalDateTime arrivalTime; + @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) + private LocalDateTime departureTime; + +} + diff --git a/src/main/java/ch/naviqore/app/model/Trip.java b/src/main/java/ch/naviqore/app/model/Trip.java new file mode 100644 index 00000000..0f6f87bc --- /dev/null +++ b/src/main/java/ch/naviqore/app/model/Trip.java @@ -0,0 +1,21 @@ +package ch.naviqore.app.model; + +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import lombok.ToString; + +import java.util.List; + +@RequiredArgsConstructor +@EqualsAndHashCode +@ToString +@Getter +public class Trip { + + private final String headSign; + private final Route route; + private final List stopTimes; + +} + diff --git a/src/main/resources/api/openapi.yaml b/src/main/resources/api/openapi.yaml index 6b79a593..470dac4b 100644 --- a/src/main/resources/api/openapi.yaml +++ b/src/main/resources/api/openapi.yaml @@ -20,12 +20,12 @@ paths: - name: limit in: query schema: - type: integer + type: integer description: The maximum number of stations to return. Defaults to `10`. - name: searchType in: query schema: - $ref: '#/components/schemas/SEARCH_TYPE' + $ref: '#/components/schemas/SEARCH_TYPE' description: The type of search to perform. Defaults to `FUZZY`. responses: '200': @@ -156,22 +156,22 @@ paths: - name: maxWalkingDuration in: query schema: - type: integer + type: integer description: The maximum walking duration in seconds. Defaults to `INFINITY`. - name: maxTransferNumber in: query schema: - type: integer + type: integer description: The maximum number of transfers between trips allowed in a connection. Defaults to `INFINITY`. - name: maxTravelTime in: query schema: - type: integer + type: integer description: The maximum travel time in seconds. Defaults to `INFINITY`. - name: minTransferTime in: query schema: - type: integer + type: integer description: The minimum transfer time between trips in seconds. Defaults to `0`. responses: '200': @@ -214,7 +214,7 @@ paths: - name: maxTravelTime in: query schema: - type: integer + type: integer description: The maximum travel time in seconds. Defaults to `INFINITY`. - name: minTransferTime in: query @@ -290,7 +290,7 @@ components: type: string format: date-time trip: - $ref: '#/components/schemas/Trip' + $ref: '#/components/schemas/Trip' EarliestArrival: type: object properties: @@ -314,7 +314,7 @@ components: headSign: type: string route: - $ref: '#/components/schemas/Route' + $ref: '#/components/schemas/Route' stopTimes: type: array items: diff --git a/src/test/java/ch/naviqore/gtfs/schedule/type/ServiceDayTimeTest.java b/src/test/java/ch/naviqore/gtfs/schedule/type/ServiceDayTimeTest.java index bca5bee5..a85af81e 100644 --- a/src/test/java/ch/naviqore/gtfs/schedule/type/ServiceDayTimeTest.java +++ b/src/test/java/ch/naviqore/gtfs/schedule/type/ServiceDayTimeTest.java @@ -40,12 +40,14 @@ void shouldThrowExceptionForNegativeHoursMinutesSeconds() { @Test void shouldThrowExceptionForInvalidMinutes() { - assertThrows(IllegalArgumentException.class, () -> new ServiceDayTime(0, ServiceDayTime.MINUTES_IN_HOUR, 0)); + assertThrows(IllegalArgumentException.class, + () -> new ServiceDayTime(0, ServiceDayTime.MINUTES_IN_HOUR, 0)); } @Test void shouldThrowExceptionForInvalidSeconds() { - assertThrows(IllegalArgumentException.class, () -> new ServiceDayTime(0, 0, ServiceDayTime.SECONDS_IN_MINUTE)); + assertThrows(IllegalArgumentException.class, + () -> new ServiceDayTime(0, 0, ServiceDayTime.SECONDS_IN_MINUTE)); } } diff --git a/src/test/resources/ch/naviqore/app/ApplicationTest.rest b/src/test/resources/ch/naviqore/app/ApplicationTest.rest new file mode 100644 index 00000000..25e41b28 --- /dev/null +++ b/src/test/resources/ch/naviqore/app/ApplicationTest.rest @@ -0,0 +1,19 @@ +### Nearest stop +GET http://localhost:8080/schedule/stops/nearest?latitude=48&longitude=8&maxDistance=500000 +Accept: application/json + +### Autocomplete stop name +GET http://localhost:8080/schedule/stops/autocomplete?query=Sta&searchType=CONTAINS +Accept: application/json + +### Departure at stop +GET http://localhost:8080/schedule/stops/Stop-1/departures?limit=3 +Accept: application/json + +### Connection between two stops +GET http://localhost:8080/routing/connections?sourceStopId=Stop-10&targetStopId=Stop-17 +Accept: application/json + +### Isoline from stop +GET http://localhost:8080/routing/isolines?sourceStopId=Stop-10&maxTransferNumber=3&maxTravelTime=7200 +Accept: application/json \ No newline at end of file From c80ed7ce44741773268da859d58ca20ca15abc76 Mon Sep 17 00:00:00 2001 From: Merlin Unterfinger Date: Mon, 27 May 2024 01:04:43 +0200 Subject: [PATCH 11/11] FIX: NAV-16 - Debug logs are back - Update log4j dependency. - Rename package and adjust package description. - Update README.md accordingly. - Move openapi.yml into same package. --- README.md | 48 ++++++++++++++++++- pom.xml | 33 ++++++++----- .../{api => ch.naviqore.app}/openapi.yaml | 0 3 files changed, 67 insertions(+), 14 deletions(-) rename src/main/resources/{api => ch.naviqore.app}/openapi.yaml (100%) diff --git a/README.md b/README.md index 81c61452..62d545ed 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,47 @@ -# Round-Based Public Transit Routing +# Public Transit Service -Implementation of the round-based public transit routing (RAPTOR) algorithm. +Public transit schedule information and connection routing service based on GTFS data and the RAPTOR algorithm. + +## Features + +- **GTFS Integration:** Integrates public transit schedules using the General Transit Feed Specification (GTFS) + format [1]. +- **Efficient Routing:** Utilizes the RAPTOR (Round-based Public Transit Routing) algorithm for optimized transit + routes [2]. +- **RESTful API:** Provides an API for querying transit schedule information and connections. + +## Installation + +1. Clone the repository: + ```bash + git clone https://github.com/naviqore/public-transit-service.git + cd public-transit-service + ``` + +2. Build the project using Maven: + + ```bash + mvn clean install + ``` + +3. Run the application: + + ```bash + mvn spring-boot:run + ``` + +## Usage + +Access the service at http://localhost:8080 to explore schedules and query transit connections. + +## License + +This project is licensed under the GPL-3.0 license. See the [LICENSE](LICENSE) file for details. + +## References + +[1] General Transit Feed Specification. (n.d.). Retrieved May 25, 2024, from [https://gtfs.org/](https://gtfs.org/) + +[2] Delling, D., Pajor, T., & Werneck, R. F. (2012). Round-Based Public Transit Routing. In *2012 Proceedings of the +Meeting on Algorithm Engineering and Experiments (ALENEX)* (pp. 130-140). +SIAM. [https://doi.org/10.1137/1.9781611972924.13](https://epubs.siam.org/doi/abs/10.1137/1.9781611972924.13) diff --git a/pom.xml b/pom.xml index 987de6f2..b5335baf 100644 --- a/pom.xml +++ b/pom.xml @@ -10,12 +10,14 @@ ch.naviqore - naviqore-raptor + public-transit-service 1.0.0-SNAPSHOT - RAPTOR - Round-based public transit routing (RAPTOR) algorithm implementation. - https://github.com/naviqore/raptor + Public Transit Service + + Public transit schedule information and connection routing service based on GTFS data and the RAPTOR algorithm. + + https://github.com/naviqore/public-transit-service @@ -40,9 +42,9 @@ - scm:git:git://github.com/naviqore/raptor.git - scm:git:ssh://github.com/naviqore/raptor.git - https://github.com/naviqore/raptor + scm:git:git://github.com/naviqore/public-transit-service.git + scm:git:ssh://github.com/naviqore/public-transit-service.git + https://github.com/naviqore/public-transit-service @@ -90,7 +92,7 @@ org.junit.jupiter junit-jupiter - 5.10.2 + 5.11.0-M1 test @@ -102,7 +104,7 @@ org.mockito mockito-junit-jupiter - 5.11.0 + 5.12.0 test @@ -127,12 +129,12 @@ org.apache.logging.log4j log4j-api - 2.23.1 + 3.0.0-beta1 org.apache.logging.log4j log4j-core - 2.23.1 + 3.0.0-beta1 @@ -163,8 +165,15 @@ io.swagger.core.v3 swagger-annotations - 2.1.12 + 2.2.22 + + + maven_central + Maven Central + https://repo.maven.apache.org/maven2/ + + diff --git a/src/main/resources/api/openapi.yaml b/src/main/resources/ch.naviqore.app/openapi.yaml similarity index 100% rename from src/main/resources/api/openapi.yaml rename to src/main/resources/ch.naviqore.app/openapi.yaml