diff --git a/.github/workflows/cibuild.yml b/.github/workflows/cibuild.yml index aa458f7d408..f799fc3cf30 100644 --- a/.github/workflows/cibuild.yml +++ b/.github/workflows/cibuild.yml @@ -33,12 +33,6 @@ jobs: distribution: temurin cache: maven - - name: Build debug client - working-directory: ./client-next - run: | - npm install - npm run build - - name: Prepare coverage agent, build and test # these are split into two steps because otherwise maven keeps long-running HTTP connections # to Maven Central open which then hang during the package phase because the Azure (Github Actions) @@ -259,11 +253,6 @@ jobs: - uses: actions/setup-node@v3 with: node-version: 18 - - name: Build debug client - working-directory: ./client-next - run: | - npm install - npm run build - name: Build container image with Jib, push to Dockerhub env: CONTAINER_REPO: docker.io/opentripplanner/opentripplanner diff --git a/.github/workflows/debug-client.yml b/.github/workflows/debug-client.yml new file mode 100644 index 00000000000..aed7943e63a --- /dev/null +++ b/.github/workflows/debug-client.yml @@ -0,0 +1,87 @@ +name: Debug client + +on: + push: + paths: + - 'client-next/**' + pull_request: + paths: + - 'client-next/**' + +# to avoid conflicts, make sure that only one workflow pushes to Github at the same time +concurrency: + group: github-push + +jobs: + debug-client: + if: github.repository_owner == 'opentripplanner' + runs-on: ubuntu-latest + timeout-minutes: 20 + steps: + # this is necessary so that the correct credentials are put into the git configuration + # when we push to dev-2.x and push the compiled output to the git repo + - uses: actions/checkout@v4 + if: github.event_name == 'push' + with: + token: ${{ secrets.CHANGELOG_TOKEN }} + fetch-depth: 0 + + # for a simple PR where we don't push, we don't need any credentials + - uses: actions/checkout@v4 + if: github.event_name == 'pull_request' + + - uses: actions/setup-node@v3 + with: + node-version: 18 + + - name: Set version + run: echo "VERSION=`date +%Y/%m/%Y-%m-%dT%H:%M`" >> $GITHUB_ENV + + - name: Build debug client + working-directory: client-next + run: | + npm install + npm run build -- --base https://cdn.jsdelivr.net/gh/opentripplanner/debug-client-assets@main/${VERSION}/ + + - name: Deploy compiled assets to repo + if: github.event_name == 'push' && github.ref == 'refs/heads/dev-2.x' + env: + REMOTE: debug-client + LOCAL_BRANCH: local-assets + REMOTE_BRANCH: main + TOKEN: ${{ secrets.CHANGELOG_TOKEN }} + run: | + # Configure git user + git config --global user.name 'OTP Bot' + git config --global user.email 'bot@opentripplanner.org' + + # Fetch the assets repo + git remote add $REMOTE https://$TOKEN@github.com/opentripplanner/debug-client-assets.git + git fetch --depth=1 $REMOTE $REMOTE_BRANCH:$LOCAL_BRANCH + + git checkout $LOCAL_BRANCH + + + # Copy the compiled output to a versioned folder + mkdir -p $VERSION + rsync -r client-next/output/* ./$VERSION/ + git add $VERSION + git commit -am "Add version ${VERSION} of debug client" + + # Push to assets repo https://github.com/opentripplanner/debug-client-assets + git push $REMOTE $LOCAL_BRANCH:$REMOTE_BRANCH + + # Switch back to the OTP code + git checkout dev-2.x + git pull --rebase + + CLIENT_HTML_OUTPUT=src/client/debug-client-preview/index.html + mkdir -p src/client/debug-client-preview/ + cp client-next/output/index.html ${CLIENT_HTML_OUTPUT} + + # just to debug + cat ${CLIENT_HTML_OUTPUT} + + git add -f ${CLIENT_HTML_OUTPUT} + git commit -m "Upgrade debug client to version ${VERSION}" + git push ${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}.git HEAD:dev-2.x diff --git a/.github/workflows/performance-test.yml b/.github/workflows/performance-test.yml index c2168a79a06..a5274d9839f 100644 --- a/.github/workflows/performance-test.yml +++ b/.github/workflows/performance-test.yml @@ -7,7 +7,7 @@ on: jobs: perf-test: - if: github.repository_owner == 'opentripplanner' && !startsWith(github.event.head_commit.message ,'Bump serialization version id for') + if: github.repository_owner == 'opentripplanner' && !startsWith(github.event.head_commit.message ,'Bump serialization version id for') && !startsWith(github.event.head_commit.message ,'Upgrade debug client to version') runs-on: performance-test strategy: fail-fast: false diff --git a/.github/workflows/post-merge.yml b/.github/workflows/post-merge.yml index 24adaed960a..1500a0f9d9e 100644 --- a/.github/workflows/post-merge.yml +++ b/.github/workflows/post-merge.yml @@ -5,6 +5,10 @@ on: - dev-2.x types: [closed] +# to avoid conflicts, make sure that only one workflow pushes to Github at the same time +concurrency: + group: github-push + jobs: changelog-entry: if: github.event.pull_request.merged && github.repository_owner == 'opentripplanner' && !contains(github.event.pull_request.labels.*.name, 'skip changelog') diff --git a/.gitignore b/.gitignore index ec589dcbd0a..b98d0263a70 100644 --- a/.gitignore +++ b/.gitignore @@ -37,7 +37,6 @@ gen-py/ node_modules/ target/ /graphs -/src/client/debug-client-preview/ # for local dev only /src/test/resources/speedtest/travelSearch-results-*.csv diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 65b259fa83c..6ccee6a89dd 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -17,6 +17,8 @@ Any message posted there will be seen by most of the contributors, some of whom time. It will also create a record of the discussion that will be useful to the larger community and often leads to issues being discussed at the twice-weekly development meetings. +## Developer meetings + OTP development meetings usually occur twice a week. These meetings are open to anyone who wants to join, even if you simply want to observe the process or ask a few questions. The most effective way to advance pull requests and collaborate is to participate directly in these meetings. The meeting diff --git a/client-next/src/components/ItineraryList/ItineraryHeaderLegContent.tsx b/client-next/src/components/ItineraryList/ItineraryHeaderLegContent.tsx index 93ee400fa2a..d1b21d46543 100644 --- a/client-next/src/components/ItineraryList/ItineraryHeaderLegContent.tsx +++ b/client-next/src/components/ItineraryList/ItineraryHeaderLegContent.tsx @@ -1,5 +1,10 @@ import { Leg } from '../../gql/graphql.ts'; import { useHeaderLegContentStyleCalculations } from './useHeaderLegContentStyleCalculations.ts'; +const modeIcons = import.meta.glob('../../static/img/mode/*.png', { as: 'url', eager: true }); + +function getModeIconUrl(leg: Leg) { + return modeIcons[`../../static/img/mode/${leg.mode.toLowerCase()}.png`]; +} export function ItineraryHeaderLegContent({ leg, @@ -22,6 +27,8 @@ export function ItineraryHeaderLegContent({ pxSpan, ); + const legIconImageUrl = getModeIconUrl(leg); + return (
{showPublicCode && {leg.line?.publicCode}} diff --git a/client-next/src/components/MapView/NavigationMarkers.tsx b/client-next/src/components/MapView/NavigationMarkers.tsx index a99590bd068..1e92a94f7a4 100644 --- a/client-next/src/components/MapView/NavigationMarkers.tsx +++ b/client-next/src/components/MapView/NavigationMarkers.tsx @@ -1,5 +1,7 @@ import { TripQueryVariables } from '../../gql/graphql.ts'; import { Marker } from 'react-map-gl'; +import markerFlagStart from '../../static/img/marker-flag-start-shadowed.png'; +import markerFlagEnd from '../../static/img/marker-flag-end-shadowed.png'; export function NavigationMarkers({ tripQueryVariables, @@ -27,7 +29,7 @@ export function NavigationMarkers({ }} anchor="bottom-right" > - + )} {tripQueryVariables.to.coordinates && ( @@ -45,7 +47,7 @@ export function NavigationMarkers({ }} anchor="bottom-right" > - + )} diff --git a/client-next/src/components/SearchBar/SearchBar.tsx b/client-next/src/components/SearchBar/SearchBar.tsx index ea1492fbe9b..dbdb5db29bf 100644 --- a/client-next/src/components/SearchBar/SearchBar.tsx +++ b/client-next/src/components/SearchBar/SearchBar.tsx @@ -14,6 +14,7 @@ import { ItineraryFilterDebugSelect } from './ItineraryFilterDebugSelect.tsx'; import Navbar from 'react-bootstrap/Navbar'; import { ServerInfoTooltip } from './ServerInfoTooltip.tsx'; import { useRef, useState } from 'react'; +import logo from '../../static/img/otp-logo.svg'; type SearchBarProps = { onRoute: () => void; @@ -31,14 +32,7 @@ export function SearchBar({ onRoute, tripQueryVariables, setTripQueryVariables,
setShowServerInfo((v) => !v)}>
- {' '} - OTP Debug Client + OTP Debug Client {showServerInfo && }
diff --git a/client-next/public/img/marker-flag-end-shadowed.png b/client-next/src/static/img/marker-flag-end-shadowed.png similarity index 100% rename from client-next/public/img/marker-flag-end-shadowed.png rename to client-next/src/static/img/marker-flag-end-shadowed.png diff --git a/client-next/public/img/marker-flag-start-shadowed.png b/client-next/src/static/img/marker-flag-start-shadowed.png similarity index 100% rename from client-next/public/img/marker-flag-start-shadowed.png rename to client-next/src/static/img/marker-flag-start-shadowed.png diff --git a/client-next/public/img/mode/air.png b/client-next/src/static/img/mode/air.png similarity index 100% rename from client-next/public/img/mode/air.png rename to client-next/src/static/img/mode/air.png diff --git a/client-next/public/img/mode/bicycle.png b/client-next/src/static/img/mode/bicycle.png similarity index 100% rename from client-next/public/img/mode/bicycle.png rename to client-next/src/static/img/mode/bicycle.png diff --git a/client-next/public/img/mode/bus.png b/client-next/src/static/img/mode/bus.png similarity index 100% rename from client-next/public/img/mode/bus.png rename to client-next/src/static/img/mode/bus.png diff --git a/client-next/public/img/mode/cableway.png b/client-next/src/static/img/mode/cableway.png similarity index 100% rename from client-next/public/img/mode/cableway.png rename to client-next/src/static/img/mode/cableway.png diff --git a/client-next/public/img/mode/car.png b/client-next/src/static/img/mode/car.png similarity index 100% rename from client-next/public/img/mode/car.png rename to client-next/src/static/img/mode/car.png diff --git a/client-next/public/img/mode/coach.png b/client-next/src/static/img/mode/coach.png similarity index 100% rename from client-next/public/img/mode/coach.png rename to client-next/src/static/img/mode/coach.png diff --git a/client-next/public/img/mode/foot.png b/client-next/src/static/img/mode/foot.png similarity index 100% rename from client-next/public/img/mode/foot.png rename to client-next/src/static/img/mode/foot.png diff --git a/client-next/public/img/mode/funicular.png b/client-next/src/static/img/mode/funicular.png similarity index 100% rename from client-next/public/img/mode/funicular.png rename to client-next/src/static/img/mode/funicular.png diff --git a/client-next/public/img/mode/metro.png b/client-next/src/static/img/mode/metro.png similarity index 100% rename from client-next/public/img/mode/metro.png rename to client-next/src/static/img/mode/metro.png diff --git a/client-next/public/img/mode/monorail.png b/client-next/src/static/img/mode/monorail.png similarity index 100% rename from client-next/public/img/mode/monorail.png rename to client-next/src/static/img/mode/monorail.png diff --git a/client-next/public/img/mode/rail.png b/client-next/src/static/img/mode/rail.png similarity index 100% rename from client-next/public/img/mode/rail.png rename to client-next/src/static/img/mode/rail.png diff --git a/client-next/public/img/mode/taxi.png b/client-next/src/static/img/mode/taxi.png similarity index 100% rename from client-next/public/img/mode/taxi.png rename to client-next/src/static/img/mode/taxi.png diff --git a/client-next/public/img/mode/tram.png b/client-next/src/static/img/mode/tram.png similarity index 100% rename from client-next/public/img/mode/tram.png rename to client-next/src/static/img/mode/tram.png diff --git a/client-next/public/img/mode/trolleybus.png b/client-next/src/static/img/mode/trolleybus.png similarity index 100% rename from client-next/public/img/mode/trolleybus.png rename to client-next/src/static/img/mode/trolleybus.png diff --git a/client-next/public/img/mode/water.png b/client-next/src/static/img/mode/water.png similarity index 100% rename from client-next/public/img/mode/water.png rename to client-next/src/static/img/mode/water.png diff --git a/client-next/public/img/otp-logo.svg b/client-next/src/static/img/otp-logo.svg similarity index 100% rename from client-next/public/img/otp-logo.svg rename to client-next/src/static/img/otp-logo.svg diff --git a/client-next/vite.config.ts b/client-next/vite.config.ts index f5fa0ab82ee..8d3ba8000c7 100644 --- a/client-next/vite.config.ts +++ b/client-next/vite.config.ts @@ -6,7 +6,7 @@ export default defineConfig({ plugins: [react()], base: '/debug-client-preview/', build: { - outDir: '../src/client/debug-client-preview', + outDir: 'output', emptyOutDir: true, }, }); diff --git a/doc-templates/Configuration.md b/doc-templates/Configuration.md index 003fe28d794..eabd4895a1f 100644 --- a/doc-templates/Configuration.md +++ b/doc-templates/Configuration.md @@ -176,7 +176,7 @@ The result will look like this: } ``` -# System-wide Configuration +## System-wide Configuration Using the file `otp-config.json` you can enable or disable different APIs and experimental [Sandbox Extensions](SandboxExtension.md). By default, all supported APIs are enabled and all @@ -185,7 +185,7 @@ Features that can be toggled in this file are generally only affect the routing but for consistency all such "feature flags", even those that would affect graph building, are managed in this one file. -## OTP Features +### OTP Features Here is a list of all features which can be toggled on/off and their default values. @@ -205,7 +205,7 @@ Here is a list of all features which can be toggled on/off and their default val ``` -# JVM configuration +## JVM configuration This section contains general recommendations for tuning the JVM in a production environment. It focuses mainly on garbage collection configuration and memory settings. @@ -213,19 +213,19 @@ See [Garbage Collector Tuning](https://docs.oracle.com/en/java/javase/17/gctunin See [Large Pages in Java](https://kstefanj.github.io/2021/05/19/large-pages-and-java.html) and [Transparent Huge Pages](https://shipilev.net/jvm/anatomy-quarks/2-transparent-huge-pages) for general information on large memory pages. -## OTP server +### OTP server The OTP server processes concurrent routing requests in real time. The main optimization goal for the OTP server is minimizing response time. -### Garbage collector +#### Garbage collector - The G1 garbage collector (default since Java 9) offers a good compromise between low latency (i.e. low GC pause time) and GC overhead. - If latency spikes are an issue, the ZGC garbage collector is an alternative. It produces in general more overhead than G1. -### Memory settings +#### Memory settings - Using Large Memory Pages can reduce pressure on the TLB cache and increase performance. - It is in general not recommended to use large memory page in _Transparent Huge Page_ mode (`-XX:+UseTransparentHugePages`) for latency-sensitive applications, since memory is allocated on-demand and this can induce latency spikes if the memory is fragmented. @@ -235,20 +235,20 @@ The physical memory can be committed upfront, at JVM startup time. This can be d Example: `-Xms18g -Xmx18g -XX:+UseTransparentHugePages -XX:+AlwaysPreTouch` -## Graph Builder +### Graph Builder The Graph Builder is the non-interactive mode used to build street graphs and transit graphs. The main optimization goal for the Graph Builder is minimizing total build time. -### Garbage collector +#### Garbage collector - In theory, the Parallel garbage collector offers the best throughput. In practice, it can be challenging to optimize the Parallel GC to build both a street graph and a transit graph, the memory usage patterns being different. - The G1 garbage collector provides in general a good compromise. -### Memory settings +#### Memory settings - Using Large Memory Pages can reduce pressure on the TLB cache and increase performance. - Since latency is not an issue, Large Memory Pages can be used indifferently in _TLBFS_ mode (`-XX:+UseHugeTLBFS`) or _Transparent Huge Page_ mode (`-XX:+UseTransparentHugePages`) diff --git a/docs/Basic-Tutorial.md b/docs/Basic-Tutorial.md index 6b993395aec..3d99d96f4da 100644 --- a/docs/Basic-Tutorial.md +++ b/docs/Basic-Tutorial.md @@ -64,6 +64,8 @@ states, from which you can prepare your own smaller bounding-box extracts using [Osmosis](http://wiki.openstreetmap.org/wiki/Osmosis#Extracting_bounding_boxes) , [osmconvert](http://wiki.openstreetmap.org/wiki/Osmconvert#Applying_Geographical_Borders), or (our favorite) [Osmium-Tool](https://osmcode.org/osmium-tool/manual.html#creating-geographic-extracts). +There is also [Protomaps](https://app.protomaps.com/) which can create custom extracts +for any region of the world with an easy to use drag and drop interface. OSM data can be delivered as XML or in the more compact binary PBF format. OpenTripPlanner consumes only PBF because it's smaller and more efficient. @@ -202,4 +204,4 @@ You can run the OTP .jar file with the `--help` option for a full list of comman ## Exploring the API -If you want to learn how to use OTP's API's, check out the [GraphQL tutorial](apis/GraphQL-Tutorial.md). \ No newline at end of file +If you want to learn how to use OTP's API's, check out the [GraphQL tutorial](apis/GraphQL-Tutorial.md). diff --git a/docs/Changelog.md b/docs/Changelog.md index cffe55c0f6f..7458295b9ba 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -44,7 +44,7 @@ based on merged pull requests. Search GitHub issues and pull requests for smalle - Fix serialization of `AtomicInteger` [#5508](https://github.com/opentripplanner/OpenTripPlanner/pull/5508) - Improve linking of fixed stops used by flex trips [#5503](https://github.com/opentripplanner/OpenTripPlanner/pull/5503) - Keep min transfer filter is not local to group-by-filters [#5436](https://github.com/opentripplanner/OpenTripPlanner/pull/5436) -- Add paging deduplication when cropping. [#5458](https://github.com/opentripplanner/OpenTripPlanner/pull/5458) +- Add paging deduplication when cropping [#5458](https://github.com/opentripplanner/OpenTripPlanner/pull/5458) - Consolidate equivalent stops from several feeds [#5429](https://github.com/opentripplanner/OpenTripPlanner/pull/5429) - Check transport mode when mapping GroupStops [#5518](https://github.com/opentripplanner/OpenTripPlanner/pull/5518) - Cleanup trip times - Part A [#5437](https://github.com/opentripplanner/OpenTripPlanner/pull/5437) @@ -63,6 +63,15 @@ based on merged pull requests. Search GitHub issues and pull requests for smalle - Make Transmodel GraphQl API an official OTP API [#5573](https://github.com/opentripplanner/OpenTripPlanner/pull/5573) - Add option to include stations in `nearest` search [#5390](https://github.com/opentripplanner/OpenTripPlanner/pull/5390) - GTFS Flex spec update: separate columns for `location_id`, `location_group_id` [#5564](https://github.com/opentripplanner/OpenTripPlanner/pull/5564) +- Report NO_TRANSIT_CONNECTION when search-window is set. [#5570](https://github.com/opentripplanner/OpenTripPlanner/pull/5570) +- Transit priority - part 3 [#5583](https://github.com/opentripplanner/OpenTripPlanner/pull/5583) +- Fix preference cost comparisons [#5586](https://github.com/opentripplanner/OpenTripPlanner/pull/5586) +- Report and throw away trip-times which fail sanity check [#5587](https://github.com/opentripplanner/OpenTripPlanner/pull/5587) +- Consider escalator edges in island pruning [#5591](https://github.com/opentripplanner/OpenTripPlanner/pull/5591) +- Create own rental preferences for bike and car in the internal model [#5562](https://github.com/opentripplanner/OpenTripPlanner/pull/5562) +- Adding situation-version to TransmodelGraphQL API [#5592](https://github.com/opentripplanner/OpenTripPlanner/pull/5592) +- Move REST API into sandbox [#5580](https://github.com/opentripplanner/OpenTripPlanner/pull/5580) +- Fix high walk reluctance leading to zero egress results for rental searches [#5605](https://github.com/opentripplanner/OpenTripPlanner/pull/5605) [](AUTOMATIC_CHANGELOG_PLACEHOLDER_DO_NOT_REMOVE) ## 2.4.0 (2023-09-13) diff --git a/docs/Configuration.md b/docs/Configuration.md index f1c0af287ab..d246b72ecab 100644 --- a/docs/Configuration.md +++ b/docs/Configuration.md @@ -203,7 +203,7 @@ The result will look like this: } ``` -# System-wide Configuration +## System-wide Configuration Using the file `otp-config.json` you can enable or disable different APIs and experimental [Sandbox Extensions](SandboxExtension.md). By default, all supported APIs are enabled and all @@ -212,7 +212,7 @@ Features that can be toggled in this file are generally only affect the routing but for consistency all such "feature flags", even those that would affect graph building, are managed in this one file. -## OTP Features +### OTP Features Here is a list of all features which can be toggled on/off and their default values. @@ -242,6 +242,7 @@ Here is a list of all features which can be toggled on/off and their default val | `FaresV2` | Enable import of GTFS-Fares v2 data. | | ✓️ | | `FlexRouting` | Enable FLEX routing. | | ✓️ | | `GoogleCloudStorage` | Enable Google Cloud Storage integration. | | ✓️ | +| `LegacyRestApi` | Enable legacy REST API. This API will be removed in the future. | ✓️ | ✓️ | | `RealtimeResolver` | When routing with ignoreRealtimeUpdates=true, add an extra step which populates results with real-time data | | ✓️ | | `ReportApi` | Enable the report API. | | ✓️ | | `RestAPIPassInDefaultConfigAsJson` | Enable a default RouteRequest to be passed in as JSON on the REST API - FOR DEBUGGING ONLY! | | | @@ -268,7 +269,7 @@ Here is a list of all features which can be toggled on/off and their default val ``` -# JVM configuration +## JVM configuration This section contains general recommendations for tuning the JVM in a production environment. It focuses mainly on garbage collection configuration and memory settings. @@ -276,19 +277,19 @@ See [Garbage Collector Tuning](https://docs.oracle.com/en/java/javase/17/gctunin See [Large Pages in Java](https://kstefanj.github.io/2021/05/19/large-pages-and-java.html) and [Transparent Huge Pages](https://shipilev.net/jvm/anatomy-quarks/2-transparent-huge-pages) for general information on large memory pages. -## OTP server +### OTP server The OTP server processes concurrent routing requests in real time. The main optimization goal for the OTP server is minimizing response time. -### Garbage collector +#### Garbage collector - The G1 garbage collector (default since Java 9) offers a good compromise between low latency (i.e. low GC pause time) and GC overhead. - If latency spikes are an issue, the ZGC garbage collector is an alternative. It produces in general more overhead than G1. -### Memory settings +#### Memory settings - Using Large Memory Pages can reduce pressure on the TLB cache and increase performance. - It is in general not recommended to use large memory page in _Transparent Huge Page_ mode (`-XX:+UseTransparentHugePages`) for latency-sensitive applications, since memory is allocated on-demand and this can induce latency spikes if the memory is fragmented. @@ -298,20 +299,20 @@ The physical memory can be committed upfront, at JVM startup time. This can be d Example: `-Xms18g -Xmx18g -XX:+UseTransparentHugePages -XX:+AlwaysPreTouch` -## Graph Builder +### Graph Builder The Graph Builder is the non-interactive mode used to build street graphs and transit graphs. The main optimization goal for the Graph Builder is minimizing total build time. -### Garbage collector +#### Garbage collector - In theory, the Parallel garbage collector offers the best throughput. In practice, it can be challenging to optimize the Parallel GC to build both a street graph and a transit graph, the memory usage patterns being different. - The G1 garbage collector provides in general a good compromise. -### Memory settings +#### Memory settings - Using Large Memory Pages can reduce pressure on the TLB cache and increase performance. - Since latency is not an issue, Large Memory Pages can be used indifferently in _TLBFS_ mode (`-XX:+UseHugeTLBFS`) or _Transparent Huge Page_ mode (`-XX:+UseTransparentHugePages`) diff --git a/docs/requirements.txt b/docs/requirements.txt index 1474504e154..8c87ef1c626 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1,4 +1,4 @@ mkdocs==1.5.3 -mkdocs-material==9.4.2 +mkdocs-material==9.5.3 mike@git+https://github.com/jimporter/mike.git@f0522f245e64687dd18384fbd86b721175711474 mkdocs-no-sitemap-plugin==0.0.1 diff --git a/pom.xml b/pom.xml index e740c782b4e..24498e76bf8 100644 --- a/pom.xml +++ b/pom.xml @@ -56,18 +56,18 @@ - 134 + 135 30.1 - 2.49 - 2.16.0 + 2.50 + 2.16.1 3.1.5 5.10.1 - 1.11.5 + 1.12.1 5.5.3 1.4.14 - 9.8.0 - 2.0.9 + 9.9.1 + 2.0.11 2.0.15 1.26 4.0.4 @@ -144,7 +144,7 @@ org.apache.maven.plugins maven-compiler-plugin - 3.12.0 + 3.12.1 21 @@ -247,7 +247,7 @@ org.apache.maven.plugins maven-surefire-plugin - 3.2.3 + 3.2.5 me.fabriciorby @@ -287,7 +287,6 @@ --add-opens java.base/jdk.internal.loader=ALL-UNNAMED --add-opens java.base/jdk.internal.ref=ALL-UNNAMED --add-opens java.base/jdk.internal.util=ALL-UNNAMED - --add-opens java.base/jdk.internal.util.jar=ALL-UNNAMED --add-opens java.base/jdk.internal.module=ALL-UNNAMED --add-opens java.base/sun.net.www.protocol.http=ALL-UNNAMED --add-opens java.base/sun.net.www.protocol.jar=ALL-UNNAMED @@ -958,7 +957,7 @@ ch.poole OpeningHoursParser - 0.27.1 + 0.28.1 diff --git a/renovate.json5 b/renovate.json5 index 5e12724db1b..42e7552c338 100644 --- a/renovate.json5 +++ b/renovate.json5 @@ -25,7 +25,8 @@ "com.microsoft.azure:azure-servicebus", "com.azure.resourcemanager:azure-resourcemanager-servicebus", "com.azure:azure-core", - "com.azure:azure-messaging-servicebus" + "com.azure:azure-messaging-servicebus", + "io.netty:netty-bom" ], "enabled": false }, @@ -33,6 +34,15 @@ "matchFiles": ["client-next/package.json"], "enabled": false }, + // gbfs-java-model patch releases are automatic dependency upgrades so we automerge + { + "matchPackageNames": [ + "org.entur.gbfs:gbfs-java-model" + ], + "matchUpdateTypes": ["patch"], + "schedule": "on the 18th day of the month", + "automerge": true + }, { // https://github.com/graphql-java-kickstart/renovate-config/blob/main/default.json "description": "GraphQL Java (ignoring snapshot builds)", @@ -53,8 +63,7 @@ "@graphql-codegen/java-resolvers", "graphql", "io.micrometer:micrometer-registry-prometheus", - "io.micrometer:micrometer-registry-influx", - "org.entur.gbfs:gbfs-java-model" + "io.micrometer:micrometer-registry-influx" ], // we don't use the 'monthly' preset because that only fires on the first day of the month // when there might already other PRs open @@ -64,7 +73,6 @@ "description": "in order to keep review burden low, don't update these quite so frequently", "matchPackagePrefixes": [ "org.apache.lucene:", - "io.netty:" ], "extends": [ "schedule:quarterly" diff --git a/src/client/debug-client-preview/index.html b/src/client/debug-client-preview/index.html new file mode 100644 index 00000000000..dfb4915efcc --- /dev/null +++ b/src/client/debug-client-preview/index.html @@ -0,0 +1,15 @@ + + + + + + + OTP Debug Client + + + + +
+ + + diff --git a/src/test/java/org/opentripplanner/api/mapping/EnumMapperTest.java b/src/ext-test/java/org/opentripplanner/ext/restapi/mapping/EnumMapperTest.java similarity index 91% rename from src/test/java/org/opentripplanner/api/mapping/EnumMapperTest.java rename to src/ext-test/java/org/opentripplanner/ext/restapi/mapping/EnumMapperTest.java index 184e6b7e6d7..35cc368fec4 100644 --- a/src/test/java/org/opentripplanner/api/mapping/EnumMapperTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/restapi/mapping/EnumMapperTest.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.mapping; +package org.opentripplanner.ext.restapi.mapping; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -8,9 +8,9 @@ import java.util.Map; import java.util.function.Function; import org.junit.jupiter.api.Test; -import org.opentripplanner.api.model.ApiAbsoluteDirection; -import org.opentripplanner.api.model.ApiRelativeDirection; -import org.opentripplanner.api.model.ApiVertexType; +import org.opentripplanner.ext.restapi.model.ApiAbsoluteDirection; +import org.opentripplanner.ext.restapi.model.ApiRelativeDirection; +import org.opentripplanner.ext.restapi.model.ApiVertexType; import org.opentripplanner.model.plan.AbsoluteDirection; import org.opentripplanner.model.plan.RelativeDirection; import org.opentripplanner.model.plan.VertexType; diff --git a/src/test/java/org/opentripplanner/api/mapping/FareMapperTest.java b/src/ext-test/java/org/opentripplanner/ext/restapi/mapping/FareMapperTest.java similarity index 95% rename from src/test/java/org/opentripplanner/api/mapping/FareMapperTest.java rename to src/ext-test/java/org/opentripplanner/ext/restapi/mapping/FareMapperTest.java index 44fb360efd2..bd1bd07aa43 100644 --- a/src/test/java/org/opentripplanner/api/mapping/FareMapperTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/restapi/mapping/FareMapperTest.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.mapping; +package org.opentripplanner.ext.restapi.mapping; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.opentripplanner.model.plan.TestItineraryBuilder.newItinerary; diff --git a/src/test/java/org/opentripplanner/api/model/ApiApiTravelOptionsMakerTest.java b/src/ext-test/java/org/opentripplanner/ext/restapi/model/ApiTravelOptionsMakerTest.java similarity index 98% rename from src/test/java/org/opentripplanner/api/model/ApiApiTravelOptionsMakerTest.java rename to src/ext-test/java/org/opentripplanner/ext/restapi/model/ApiTravelOptionsMakerTest.java index 9429151a422..fdcd0a7fe20 100644 --- a/src/test/java/org/opentripplanner/api/model/ApiApiTravelOptionsMakerTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/restapi/model/ApiTravelOptionsMakerTest.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.model; +package org.opentripplanner.ext.restapi.model; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -11,7 +11,7 @@ /** * Created by mabu on 28.7.2015. */ -public class ApiApiTravelOptionsMakerTest { +public class ApiTravelOptionsMakerTest { @Test public void testMakeOptions() throws Exception { diff --git a/src/test/java/org/opentripplanner/api/model/ApiWalkStepTest.java b/src/ext-test/java/org/opentripplanner/ext/restapi/model/ApiWalkStepTest.java similarity index 93% rename from src/test/java/org/opentripplanner/api/model/ApiWalkStepTest.java rename to src/ext-test/java/org/opentripplanner/ext/restapi/model/ApiWalkStepTest.java index 44be1348eee..7f6909bfc2c 100644 --- a/src/test/java/org/opentripplanner/api/model/ApiWalkStepTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/restapi/model/ApiWalkStepTest.java @@ -1,8 +1,7 @@ -package org.opentripplanner.api.model; +package org.opentripplanner.ext.restapi.model; import static org.junit.jupiter.api.Assertions.assertEquals; -import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/src/test/java/org/opentripplanner/api/parameter/ApiRequestModeTest.java b/src/ext-test/java/org/opentripplanner/ext/restapi/parameter/ApiRequestModeTest.java similarity index 69% rename from src/test/java/org/opentripplanner/api/parameter/ApiRequestModeTest.java rename to src/ext-test/java/org/opentripplanner/ext/restapi/parameter/ApiRequestModeTest.java index caf26510b2a..13cfc43c59c 100644 --- a/src/test/java/org/opentripplanner/api/parameter/ApiRequestModeTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/restapi/parameter/ApiRequestModeTest.java @@ -1,10 +1,12 @@ -package org.opentripplanner.api.parameter; +package org.opentripplanner.ext.restapi.parameter; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.opentripplanner.transit.model.basic.TransitMode.CARPOOL; import java.util.List; +import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; +import org.opentripplanner.api.parameter.ApiRequestMode; class ApiRequestModeTest { diff --git a/src/test/java/org/opentripplanner/api/parameter/QualifiedModeSetTest.java b/src/ext-test/java/org/opentripplanner/ext/restapi/parameter/QualifiedModeSetTest.java similarity index 97% rename from src/test/java/org/opentripplanner/api/parameter/QualifiedModeSetTest.java rename to src/ext-test/java/org/opentripplanner/ext/restapi/parameter/QualifiedModeSetTest.java index ba5a39abe89..ad344713a74 100644 --- a/src/test/java/org/opentripplanner/api/parameter/QualifiedModeSetTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/restapi/parameter/QualifiedModeSetTest.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.parameter; +package org.opentripplanner.ext.restapi.parameter; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; @@ -26,6 +26,8 @@ import jakarta.ws.rs.BadRequestException; import java.util.Set; import org.junit.jupiter.api.Test; +import org.opentripplanner.api.parameter.QualifiedMode; +import org.opentripplanner.api.parameter.QualifiedModeSet; import org.opentripplanner.routing.api.request.RequestModes; import org.opentripplanner.transit.model.basic.TransitMode; diff --git a/src/test/java/org/opentripplanner/api/parameter/QualifiedModeTest.java b/src/ext-test/java/org/opentripplanner/ext/restapi/parameter/QualifiedModeTest.java similarity index 82% rename from src/test/java/org/opentripplanner/api/parameter/QualifiedModeTest.java rename to src/ext-test/java/org/opentripplanner/ext/restapi/parameter/QualifiedModeTest.java index e4c4c9448fc..3a682ba40c9 100644 --- a/src/test/java/org/opentripplanner/api/parameter/QualifiedModeTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/restapi/parameter/QualifiedModeTest.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.parameter; +package org.opentripplanner.ext.restapi.parameter; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -6,6 +6,9 @@ import java.util.Set; import java.util.stream.Collectors; import org.junit.jupiter.api.Test; +import org.opentripplanner.api.parameter.ApiRequestMode; +import org.opentripplanner.api.parameter.QualifiedMode; +import org.opentripplanner.api.parameter.Qualifier; public class QualifiedModeTest { diff --git a/src/ext/java/org/opentripplanner/ext/geocoder/GeocoderResource.java b/src/ext/java/org/opentripplanner/ext/geocoder/GeocoderResource.java index d2eafc91e5c..39ed6da297c 100644 --- a/src/ext/java/org/opentripplanner/ext/geocoder/GeocoderResource.java +++ b/src/ext/java/org/opentripplanner/ext/geocoder/GeocoderResource.java @@ -14,7 +14,7 @@ import java.util.List; import java.util.Objects; import java.util.stream.Collectors; -import org.opentripplanner.api.mapping.FeedScopedIdMapper; +import org.opentripplanner.ext.restapi.mapping.FeedScopedIdMapper; import org.opentripplanner.standalone.api.OtpServerRequestContext; import org.opentripplanner.transit.model.site.StopLocation; diff --git a/src/ext/java/org/opentripplanner/ext/geocoder/LuceneIndex.java b/src/ext/java/org/opentripplanner/ext/geocoder/LuceneIndex.java index 7037fd19361..71b0cf67b34 100644 --- a/src/ext/java/org/opentripplanner/ext/geocoder/LuceneIndex.java +++ b/src/ext/java/org/opentripplanner/ext/geocoder/LuceneIndex.java @@ -17,7 +17,7 @@ import org.apache.lucene.analysis.standard.StandardAnalyzer; import org.apache.lucene.codecs.Codec; import org.apache.lucene.codecs.PostingsFormat; -import org.apache.lucene.codecs.lucene95.Lucene95Codec; +import org.apache.lucene.codecs.lucene99.Lucene99Codec; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field.Store; import org.apache.lucene.document.StoredField; @@ -33,7 +33,7 @@ import org.apache.lucene.search.FuzzyQuery; import org.apache.lucene.search.PrefixQuery; import org.apache.lucene.search.TermQuery; -import org.apache.lucene.search.suggest.document.Completion90PostingsFormat; +import org.apache.lucene.search.suggest.document.Completion99PostingsFormat; import org.apache.lucene.search.suggest.document.CompletionAnalyzer; import org.apache.lucene.search.suggest.document.ContextQuery; import org.apache.lucene.search.suggest.document.ContextSuggestField; @@ -191,8 +191,8 @@ private static StopCluster toStopCluster(Document document) { static IndexWriterConfig iwcWithSuggestField(Analyzer analyzer, final Set suggestFields) { IndexWriterConfig iwc = new IndexWriterConfig(analyzer); - Codec filterCodec = new Lucene95Codec() { - final PostingsFormat postingsFormat = new Completion90PostingsFormat(); + Codec filterCodec = new Lucene99Codec() { + final PostingsFormat postingsFormat = new Completion99PostingsFormat(); @Override public PostingsFormat getPostingsFormatForField(String field) { diff --git a/src/main/java/org/opentripplanner/api/mapping/AbsoluteDirectionMapper.java b/src/ext/java/org/opentripplanner/ext/restapi/mapping/AbsoluteDirectionMapper.java similarity index 88% rename from src/main/java/org/opentripplanner/api/mapping/AbsoluteDirectionMapper.java rename to src/ext/java/org/opentripplanner/ext/restapi/mapping/AbsoluteDirectionMapper.java index 59bb0d77955..8500323c032 100644 --- a/src/main/java/org/opentripplanner/api/mapping/AbsoluteDirectionMapper.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/mapping/AbsoluteDirectionMapper.java @@ -1,6 +1,6 @@ -package org.opentripplanner.api.mapping; +package org.opentripplanner.ext.restapi.mapping; -import org.opentripplanner.api.model.ApiAbsoluteDirection; +import org.opentripplanner.ext.restapi.model.ApiAbsoluteDirection; import org.opentripplanner.model.plan.AbsoluteDirection; public class AbsoluteDirectionMapper { diff --git a/src/main/java/org/opentripplanner/api/mapping/AgencyMapper.java b/src/ext/java/org/opentripplanner/ext/restapi/mapping/AgencyMapper.java similarity index 89% rename from src/main/java/org/opentripplanner/api/mapping/AgencyMapper.java rename to src/ext/java/org/opentripplanner/ext/restapi/mapping/AgencyMapper.java index 9600400d373..4ea3ebb5209 100644 --- a/src/main/java/org/opentripplanner/api/mapping/AgencyMapper.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/mapping/AgencyMapper.java @@ -1,9 +1,9 @@ -package org.opentripplanner.api.mapping; +package org.opentripplanner.ext.restapi.mapping; import java.util.Collection; import java.util.List; import java.util.stream.Collectors; -import org.opentripplanner.api.model.ApiAgency; +import org.opentripplanner.ext.restapi.model.ApiAgency; import org.opentripplanner.transit.model.organization.Agency; public class AgencyMapper { diff --git a/src/main/java/org/opentripplanner/api/mapping/AlertMapper.java b/src/ext/java/org/opentripplanner/ext/restapi/mapping/AlertMapper.java similarity index 92% rename from src/main/java/org/opentripplanner/api/mapping/AlertMapper.java rename to src/ext/java/org/opentripplanner/ext/restapi/mapping/AlertMapper.java index e01961a5dca..8fbfa71111f 100644 --- a/src/main/java/org/opentripplanner/api/mapping/AlertMapper.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/mapping/AlertMapper.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.mapping; +package org.opentripplanner.ext.restapi.mapping; import java.time.Instant; import java.util.Collection; @@ -7,7 +7,7 @@ import java.util.Locale; import java.util.Optional; import java.util.stream.Collectors; -import org.opentripplanner.api.model.ApiAlert; +import org.opentripplanner.ext.restapi.model.ApiAlert; import org.opentripplanner.routing.alertpatch.TransitAlert; public class AlertMapper { diff --git a/src/main/java/org/opentripplanner/api/mapping/BikeAccessMapper.java b/src/ext/java/org/opentripplanner/ext/restapi/mapping/BikeAccessMapper.java similarity index 86% rename from src/main/java/org/opentripplanner/api/mapping/BikeAccessMapper.java rename to src/ext/java/org/opentripplanner/ext/restapi/mapping/BikeAccessMapper.java index 43c00ef8227..3ceb86b4459 100644 --- a/src/main/java/org/opentripplanner/api/mapping/BikeAccessMapper.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/mapping/BikeAccessMapper.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.mapping; +package org.opentripplanner.ext.restapi.mapping; import org.opentripplanner.transit.model.network.BikeAccess; diff --git a/src/main/java/org/opentripplanner/api/mapping/BookingInfoMapper.java b/src/ext/java/org/opentripplanner/ext/restapi/mapping/BookingInfoMapper.java similarity index 88% rename from src/main/java/org/opentripplanner/api/mapping/BookingInfoMapper.java rename to src/ext/java/org/opentripplanner/ext/restapi/mapping/BookingInfoMapper.java index 4f1eb0c6249..4aa8b4a46b1 100644 --- a/src/main/java/org/opentripplanner/api/mapping/BookingInfoMapper.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/mapping/BookingInfoMapper.java @@ -1,6 +1,6 @@ -package org.opentripplanner.api.mapping; +package org.opentripplanner.ext.restapi.mapping; -import org.opentripplanner.api.model.ApiBookingInfo; +import org.opentripplanner.ext.restapi.model.ApiBookingInfo; import org.opentripplanner.model.BookingInfo; public class BookingInfoMapper { diff --git a/src/main/java/org/opentripplanner/api/mapping/BookingMethodMapper.java b/src/ext/java/org/opentripplanner/ext/restapi/mapping/BookingMethodMapper.java similarity index 94% rename from src/main/java/org/opentripplanner/api/mapping/BookingMethodMapper.java rename to src/ext/java/org/opentripplanner/ext/restapi/mapping/BookingMethodMapper.java index b938c1813d2..9b61ff39543 100644 --- a/src/main/java/org/opentripplanner/api/mapping/BookingMethodMapper.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/mapping/BookingMethodMapper.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.mapping; +package org.opentripplanner.ext.restapi.mapping; import java.util.EnumSet; import java.util.Set; diff --git a/src/main/java/org/opentripplanner/api/mapping/BookingTimeMapper.java b/src/ext/java/org/opentripplanner/ext/restapi/mapping/BookingTimeMapper.java similarity index 71% rename from src/main/java/org/opentripplanner/api/mapping/BookingTimeMapper.java rename to src/ext/java/org/opentripplanner/ext/restapi/mapping/BookingTimeMapper.java index 3a779cbeed4..e40309e9137 100644 --- a/src/main/java/org/opentripplanner/api/mapping/BookingTimeMapper.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/mapping/BookingTimeMapper.java @@ -1,6 +1,6 @@ -package org.opentripplanner.api.mapping; +package org.opentripplanner.ext.restapi.mapping; -import org.opentripplanner.api.model.ApiBookingTime; +import org.opentripplanner.ext.restapi.model.ApiBookingTime; import org.opentripplanner.model.BookingTime; public class BookingTimeMapper { diff --git a/src/main/java/org/opentripplanner/api/mapping/ContactInfoMapper.java b/src/ext/java/org/opentripplanner/ext/restapi/mapping/ContactInfoMapper.java similarity index 80% rename from src/main/java/org/opentripplanner/api/mapping/ContactInfoMapper.java rename to src/ext/java/org/opentripplanner/ext/restapi/mapping/ContactInfoMapper.java index d12a06f8e30..452e15a0cb5 100644 --- a/src/main/java/org/opentripplanner/api/mapping/ContactInfoMapper.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/mapping/ContactInfoMapper.java @@ -1,6 +1,6 @@ -package org.opentripplanner.api.mapping; +package org.opentripplanner.ext.restapi.mapping; -import org.opentripplanner.api.model.ApiContactInfo; +import org.opentripplanner.ext.restapi.model.ApiContactInfo; import org.opentripplanner.transit.model.organization.ContactInfo; public class ContactInfoMapper { diff --git a/src/main/java/org/opentripplanner/api/mapping/DirectionMapper.java b/src/ext/java/org/opentripplanner/ext/restapi/mapping/DirectionMapper.java similarity index 83% rename from src/main/java/org/opentripplanner/api/mapping/DirectionMapper.java rename to src/ext/java/org/opentripplanner/ext/restapi/mapping/DirectionMapper.java index 22decc21f81..ea510b1fdc7 100644 --- a/src/main/java/org/opentripplanner/api/mapping/DirectionMapper.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/mapping/DirectionMapper.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.mapping; +package org.opentripplanner.ext.restapi.mapping; import org.opentripplanner.transit.model.timetable.Direction; diff --git a/src/main/java/org/opentripplanner/api/mapping/ElevationMapper.java b/src/ext/java/org/opentripplanner/ext/restapi/mapping/ElevationMapper.java similarity index 92% rename from src/main/java/org/opentripplanner/api/mapping/ElevationMapper.java rename to src/ext/java/org/opentripplanner/ext/restapi/mapping/ElevationMapper.java index de5c9f46fdb..192848f04d6 100644 --- a/src/main/java/org/opentripplanner/api/mapping/ElevationMapper.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/mapping/ElevationMapper.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.mapping; +package org.opentripplanner.ext.restapi.mapping; import org.opentripplanner.model.plan.ElevationProfile; diff --git a/src/main/java/org/opentripplanner/api/mapping/FareMapper.java b/src/ext/java/org/opentripplanner/ext/restapi/mapping/FareMapper.java similarity index 89% rename from src/main/java/org/opentripplanner/api/mapping/FareMapper.java rename to src/ext/java/org/opentripplanner/ext/restapi/mapping/FareMapper.java index 4d682a1d32c..a6020c6bf37 100644 --- a/src/main/java/org/opentripplanner/api/mapping/FareMapper.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/mapping/FareMapper.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.mapping; +package org.opentripplanner.ext.restapi.mapping; import com.google.common.collect.Multimap; import java.util.AbstractMap.SimpleEntry; @@ -10,13 +10,13 @@ import java.util.Optional; import java.util.stream.Collectors; import javax.annotation.Nullable; -import org.opentripplanner.api.model.ApiCurrency; -import org.opentripplanner.api.model.ApiFareComponent; -import org.opentripplanner.api.model.ApiFareProduct; -import org.opentripplanner.api.model.ApiFareQualifier; -import org.opentripplanner.api.model.ApiItineraryFares; -import org.opentripplanner.api.model.ApiLegProducts; -import org.opentripplanner.api.model.ApiMoney; +import org.opentripplanner.ext.restapi.model.ApiCurrency; +import org.opentripplanner.ext.restapi.model.ApiFareComponent; +import org.opentripplanner.ext.restapi.model.ApiFareProduct; +import org.opentripplanner.ext.restapi.model.ApiFareQualifier; +import org.opentripplanner.ext.restapi.model.ApiItineraryFares; +import org.opentripplanner.ext.restapi.model.ApiLegProducts; +import org.opentripplanner.ext.restapi.model.ApiMoney; import org.opentripplanner.model.fare.FareMedium; import org.opentripplanner.model.fare.FareProduct; import org.opentripplanner.model.fare.FareProductUse; diff --git a/src/main/java/org/opentripplanner/api/mapping/FeedInfoMapper.java b/src/ext/java/org/opentripplanner/ext/restapi/mapping/FeedInfoMapper.java similarity index 84% rename from src/main/java/org/opentripplanner/api/mapping/FeedInfoMapper.java rename to src/ext/java/org/opentripplanner/ext/restapi/mapping/FeedInfoMapper.java index b8262d726fe..203ade5749e 100644 --- a/src/main/java/org/opentripplanner/api/mapping/FeedInfoMapper.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/mapping/FeedInfoMapper.java @@ -1,6 +1,6 @@ -package org.opentripplanner.api.mapping; +package org.opentripplanner.ext.restapi.mapping; -import org.opentripplanner.api.model.ApiFeedInfo; +import org.opentripplanner.ext.restapi.model.ApiFeedInfo; import org.opentripplanner.model.FeedInfo; public class FeedInfoMapper { diff --git a/src/main/java/org/opentripplanner/api/mapping/FeedScopedIdMapper.java b/src/ext/java/org/opentripplanner/ext/restapi/mapping/FeedScopedIdMapper.java similarity index 95% rename from src/main/java/org/opentripplanner/api/mapping/FeedScopedIdMapper.java rename to src/ext/java/org/opentripplanner/ext/restapi/mapping/FeedScopedIdMapper.java index d33d7c53bc1..619c306fbbc 100644 --- a/src/main/java/org/opentripplanner/api/mapping/FeedScopedIdMapper.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/mapping/FeedScopedIdMapper.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.mapping; +package org.opentripplanner.ext.restapi.mapping; import jakarta.ws.rs.BadRequestException; import org.opentripplanner.transit.model.framework.AbstractTransitEntity; diff --git a/src/main/java/org/opentripplanner/api/mapping/ItineraryMapper.java b/src/ext/java/org/opentripplanner/ext/restapi/mapping/ItineraryMapper.java similarity index 94% rename from src/main/java/org/opentripplanner/api/mapping/ItineraryMapper.java rename to src/ext/java/org/opentripplanner/ext/restapi/mapping/ItineraryMapper.java index cf14eda73dd..d87cf33d71c 100644 --- a/src/main/java/org/opentripplanner/api/mapping/ItineraryMapper.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/mapping/ItineraryMapper.java @@ -1,11 +1,11 @@ -package org.opentripplanner.api.mapping; +package org.opentripplanner.ext.restapi.mapping; import java.util.Collection; import java.util.GregorianCalendar; import java.util.List; import java.util.Locale; import java.util.stream.Collectors; -import org.opentripplanner.api.model.ApiItinerary; +import org.opentripplanner.ext.restapi.model.ApiItinerary; import org.opentripplanner.model.plan.Itinerary; public class ItineraryMapper { diff --git a/src/main/java/org/opentripplanner/api/mapping/LegMapper.java b/src/ext/java/org/opentripplanner/ext/restapi/mapping/LegMapper.java similarity index 92% rename from src/main/java/org/opentripplanner/api/mapping/LegMapper.java rename to src/ext/java/org/opentripplanner/ext/restapi/mapping/LegMapper.java index cc139e5180d..766262bca89 100644 --- a/src/main/java/org/opentripplanner/api/mapping/LegMapper.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/mapping/LegMapper.java @@ -1,15 +1,17 @@ -package org.opentripplanner.api.mapping; +package org.opentripplanner.ext.restapi.mapping; -import static org.opentripplanner.api.mapping.ElevationMapper.mapElevation; +import static org.opentripplanner.ext.restapi.mapping.ElevationMapper.mapElevation; import java.time.ZonedDateTime; import java.util.ArrayList; import java.util.GregorianCalendar; import java.util.List; import java.util.Locale; -import org.opentripplanner.api.model.ApiAlert; -import org.opentripplanner.api.model.ApiLeg; +import org.opentripplanner.apis.support.mapping.StreetNoteMapper; +import org.opentripplanner.ext.restapi.model.ApiAlert; +import org.opentripplanner.ext.restapi.model.ApiLeg; import org.opentripplanner.framework.geometry.EncodedPolyline; +import org.opentripplanner.framework.i18n.I18NStringMapper; import org.opentripplanner.model.PickDrop; import org.opentripplanner.model.plan.Leg; import org.opentripplanner.model.plan.StreetLeg; @@ -18,7 +20,7 @@ public class LegMapper { private final WalkStepMapper walkStepMapper; - private final StreetNoteMaperMapper streetNoteMaperMapper; + private final StreetNoteMapper streetNoteMaperMapper; private final AlertMapper alertMapper; private final PlaceMapper placeMapper; private final boolean addIntermediateStops; @@ -27,7 +29,7 @@ public class LegMapper { public LegMapper(Locale locale, boolean addIntermediateStops) { this.walkStepMapper = new WalkStepMapper(locale); - this.streetNoteMaperMapper = new StreetNoteMaperMapper(locale); + this.streetNoteMaperMapper = new StreetNoteMapper(locale); this.alertMapper = new AlertMapper(locale); this.placeMapper = new PlaceMapper(locale); this.addIntermediateStops = addIntermediateStops; diff --git a/src/main/java/org/opentripplanner/api/mapping/LocalDateMapper.java b/src/ext/java/org/opentripplanner/ext/restapi/mapping/LocalDateMapper.java similarity index 89% rename from src/main/java/org/opentripplanner/api/mapping/LocalDateMapper.java rename to src/ext/java/org/opentripplanner/ext/restapi/mapping/LocalDateMapper.java index 334efa8c6e8..940bcc13d54 100644 --- a/src/main/java/org/opentripplanner/api/mapping/LocalDateMapper.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/mapping/LocalDateMapper.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.mapping; +package org.opentripplanner.ext.restapi.mapping; import java.time.LocalDate; import org.opentripplanner.framework.time.ServiceDateUtils; diff --git a/src/main/java/org/opentripplanner/api/mapping/ModeMapper.java b/src/ext/java/org/opentripplanner/ext/restapi/mapping/ModeMapper.java similarity index 97% rename from src/main/java/org/opentripplanner/api/mapping/ModeMapper.java rename to src/ext/java/org/opentripplanner/ext/restapi/mapping/ModeMapper.java index 3276de080c3..49bd2619149 100644 --- a/src/main/java/org/opentripplanner/api/mapping/ModeMapper.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/mapping/ModeMapper.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.mapping; +package org.opentripplanner.ext.restapi.mapping; import java.util.List; import java.util.Set; diff --git a/src/main/java/org/opentripplanner/api/mapping/PlaceMapper.java b/src/ext/java/org/opentripplanner/ext/restapi/mapping/PlaceMapper.java similarity index 93% rename from src/main/java/org/opentripplanner/api/mapping/PlaceMapper.java rename to src/ext/java/org/opentripplanner/ext/restapi/mapping/PlaceMapper.java index e806c5615d2..b1eb3410af8 100644 --- a/src/main/java/org/opentripplanner/api/mapping/PlaceMapper.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/mapping/PlaceMapper.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.mapping; +package org.opentripplanner.ext.restapi.mapping; import java.time.ZonedDateTime; import java.util.ArrayList; @@ -8,9 +8,10 @@ import java.util.Locale; import java.util.Optional; import java.util.stream.Collectors; -import org.opentripplanner.api.model.ApiPlace; -import org.opentripplanner.api.model.ApiVehicleParkingSpaces; -import org.opentripplanner.api.model.ApiVehicleParkingWithEntrance; +import org.opentripplanner.ext.restapi.model.ApiPlace; +import org.opentripplanner.ext.restapi.model.ApiVehicleParkingSpaces; +import org.opentripplanner.ext.restapi.model.ApiVehicleParkingWithEntrance; +import org.opentripplanner.framework.i18n.I18NStringMapper; import org.opentripplanner.model.plan.Place; import org.opentripplanner.model.plan.StopArrival; import org.opentripplanner.model.plan.VehicleParkingWithEntrance; diff --git a/src/main/java/org/opentripplanner/api/mapping/RelativeDirectionMapper.java b/src/ext/java/org/opentripplanner/ext/restapi/mapping/RelativeDirectionMapper.java similarity index 91% rename from src/main/java/org/opentripplanner/api/mapping/RelativeDirectionMapper.java rename to src/ext/java/org/opentripplanner/ext/restapi/mapping/RelativeDirectionMapper.java index 78c4495292c..a1bdd145a55 100644 --- a/src/main/java/org/opentripplanner/api/mapping/RelativeDirectionMapper.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/mapping/RelativeDirectionMapper.java @@ -1,6 +1,6 @@ -package org.opentripplanner.api.mapping; +package org.opentripplanner.ext.restapi.mapping; -import org.opentripplanner.api.model.ApiRelativeDirection; +import org.opentripplanner.ext.restapi.model.ApiRelativeDirection; import org.opentripplanner.model.plan.RelativeDirection; public class RelativeDirectionMapper { diff --git a/src/main/java/org/opentripplanner/api/mapping/RouteMapper.java b/src/ext/java/org/opentripplanner/ext/restapi/mapping/RouteMapper.java similarity index 90% rename from src/main/java/org/opentripplanner/api/mapping/RouteMapper.java rename to src/ext/java/org/opentripplanner/ext/restapi/mapping/RouteMapper.java index f64a350092c..decee369a17 100644 --- a/src/main/java/org/opentripplanner/api/mapping/RouteMapper.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/mapping/RouteMapper.java @@ -1,10 +1,11 @@ -package org.opentripplanner.api.mapping; +package org.opentripplanner.ext.restapi.mapping; import java.util.Collection; import java.util.List; import java.util.stream.Collectors; -import org.opentripplanner.api.model.ApiRoute; -import org.opentripplanner.api.model.ApiRouteShort; +import org.opentripplanner.ext.restapi.model.ApiRoute; +import org.opentripplanner.ext.restapi.model.ApiRouteShort; +import org.opentripplanner.framework.i18n.I18NStringMapper; import org.opentripplanner.transit.model.network.Route; import org.opentripplanner.transit.model.organization.Branding; diff --git a/src/main/java/org/opentripplanner/api/mapping/RouteTypeMapper.java b/src/ext/java/org/opentripplanner/ext/restapi/mapping/RouteTypeMapper.java similarity index 92% rename from src/main/java/org/opentripplanner/api/mapping/RouteTypeMapper.java rename to src/ext/java/org/opentripplanner/ext/restapi/mapping/RouteTypeMapper.java index af300b1d39a..9dede395e80 100644 --- a/src/main/java/org/opentripplanner/api/mapping/RouteTypeMapper.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/mapping/RouteTypeMapper.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.mapping; +package org.opentripplanner.ext.restapi.mapping; import org.opentripplanner.transit.model.basic.TransitMode; diff --git a/src/main/java/org/opentripplanner/api/mapping/StopMapper.java b/src/ext/java/org/opentripplanner/ext/restapi/mapping/StopMapper.java similarity index 93% rename from src/main/java/org/opentripplanner/api/mapping/StopMapper.java rename to src/ext/java/org/opentripplanner/ext/restapi/mapping/StopMapper.java index 954584fd76f..9e3c8b04262 100644 --- a/src/main/java/org/opentripplanner/api/mapping/StopMapper.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/mapping/StopMapper.java @@ -1,10 +1,11 @@ -package org.opentripplanner.api.mapping; +package org.opentripplanner.ext.restapi.mapping; import java.util.Collection; import java.util.List; import java.util.stream.Collectors; -import org.opentripplanner.api.model.ApiStop; -import org.opentripplanner.api.model.ApiStopShort; +import org.opentripplanner.ext.restapi.model.ApiStop; +import org.opentripplanner.ext.restapi.model.ApiStopShort; +import org.opentripplanner.framework.i18n.I18NStringMapper; import org.opentripplanner.transit.model.site.StopLocation; public class StopMapper { diff --git a/src/main/java/org/opentripplanner/api/mapping/StopTimesInPatternMapper.java b/src/ext/java/org/opentripplanner/ext/restapi/mapping/StopTimesInPatternMapper.java similarity index 86% rename from src/main/java/org/opentripplanner/api/mapping/StopTimesInPatternMapper.java rename to src/ext/java/org/opentripplanner/ext/restapi/mapping/StopTimesInPatternMapper.java index 66da0071959..d917bac9203 100644 --- a/src/main/java/org/opentripplanner/api/mapping/StopTimesInPatternMapper.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/mapping/StopTimesInPatternMapper.java @@ -1,9 +1,9 @@ -package org.opentripplanner.api.mapping; +package org.opentripplanner.ext.restapi.mapping; import java.util.Collection; import java.util.List; import java.util.stream.Collectors; -import org.opentripplanner.api.model.ApiStopTimesInPattern; +import org.opentripplanner.ext.restapi.model.ApiStopTimesInPattern; import org.opentripplanner.model.StopTimesInPattern; public class StopTimesInPatternMapper { diff --git a/src/main/java/org/opentripplanner/api/mapping/SystemNoticeMapper.java b/src/ext/java/org/opentripplanner/ext/restapi/mapping/SystemNoticeMapper.java similarity index 87% rename from src/main/java/org/opentripplanner/api/mapping/SystemNoticeMapper.java rename to src/ext/java/org/opentripplanner/ext/restapi/mapping/SystemNoticeMapper.java index f30a62d2d97..1c79a4a7074 100644 --- a/src/main/java/org/opentripplanner/api/mapping/SystemNoticeMapper.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/mapping/SystemNoticeMapper.java @@ -1,9 +1,9 @@ -package org.opentripplanner.api.mapping; +package org.opentripplanner.ext.restapi.mapping; import java.util.Collection; import java.util.List; import java.util.stream.Collectors; -import org.opentripplanner.api.model.ApiSystemNotice; +import org.opentripplanner.ext.restapi.model.ApiSystemNotice; import org.opentripplanner.model.SystemNotice; public final class SystemNoticeMapper { diff --git a/src/main/java/org/opentripplanner/api/mapping/TransferMapper.java b/src/ext/java/org/opentripplanner/ext/restapi/mapping/TransferMapper.java similarity index 77% rename from src/main/java/org/opentripplanner/api/mapping/TransferMapper.java rename to src/ext/java/org/opentripplanner/ext/restapi/mapping/TransferMapper.java index 3004d86aa44..49b87f25779 100644 --- a/src/main/java/org/opentripplanner/api/mapping/TransferMapper.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/mapping/TransferMapper.java @@ -1,6 +1,6 @@ -package org.opentripplanner.api.mapping; +package org.opentripplanner.ext.restapi.mapping; -import org.opentripplanner.api.model.ApiTransfer; +import org.opentripplanner.ext.restapi.model.ApiTransfer; import org.opentripplanner.model.PathTransfer; public class TransferMapper { diff --git a/src/main/java/org/opentripplanner/api/mapping/TripMapper.java b/src/ext/java/org/opentripplanner/ext/restapi/mapping/TripMapper.java similarity index 90% rename from src/main/java/org/opentripplanner/api/mapping/TripMapper.java rename to src/ext/java/org/opentripplanner/ext/restapi/mapping/TripMapper.java index 33df525a9a7..f4894a4a7a3 100644 --- a/src/main/java/org/opentripplanner/api/mapping/TripMapper.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/mapping/TripMapper.java @@ -1,10 +1,11 @@ -package org.opentripplanner.api.mapping; +package org.opentripplanner.ext.restapi.mapping; import java.util.List; import java.util.stream.Collectors; import java.util.stream.Stream; -import org.opentripplanner.api.model.ApiTrip; -import org.opentripplanner.api.model.ApiTripShort; +import org.opentripplanner.ext.restapi.model.ApiTrip; +import org.opentripplanner.ext.restapi.model.ApiTripShort; +import org.opentripplanner.framework.i18n.I18NStringMapper; import org.opentripplanner.transit.model.framework.FeedScopedId; import org.opentripplanner.transit.model.timetable.Trip; diff --git a/src/main/java/org/opentripplanner/api/mapping/TripPatternMapper.java b/src/ext/java/org/opentripplanner/ext/restapi/mapping/TripPatternMapper.java similarity index 88% rename from src/main/java/org/opentripplanner/api/mapping/TripPatternMapper.java rename to src/ext/java/org/opentripplanner/ext/restapi/mapping/TripPatternMapper.java index 439d2b5fe2f..ba68979c73f 100644 --- a/src/main/java/org/opentripplanner/api/mapping/TripPatternMapper.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/mapping/TripPatternMapper.java @@ -1,11 +1,11 @@ -package org.opentripplanner.api.mapping; +package org.opentripplanner.ext.restapi.mapping; import java.util.Collection; import java.util.List; import java.util.function.Supplier; import java.util.stream.Collectors; -import org.opentripplanner.api.model.ApiPatternDetail; -import org.opentripplanner.api.model.ApiPatternShort; +import org.opentripplanner.ext.restapi.model.ApiPatternDetail; +import org.opentripplanner.ext.restapi.model.ApiPatternShort; import org.opentripplanner.transit.model.network.TripPattern; public class TripPatternMapper { diff --git a/src/main/java/org/opentripplanner/api/mapping/TripPlanMapper.java b/src/ext/java/org/opentripplanner/ext/restapi/mapping/TripPlanMapper.java similarity index 89% rename from src/main/java/org/opentripplanner/api/mapping/TripPlanMapper.java rename to src/ext/java/org/opentripplanner/ext/restapi/mapping/TripPlanMapper.java index 8c5459af8ed..891afcf9542 100644 --- a/src/main/java/org/opentripplanner/api/mapping/TripPlanMapper.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/mapping/TripPlanMapper.java @@ -1,8 +1,8 @@ -package org.opentripplanner.api.mapping; +package org.opentripplanner.ext.restapi.mapping; import java.util.Date; import java.util.Locale; -import org.opentripplanner.api.model.ApiTripPlan; +import org.opentripplanner.ext.restapi.model.ApiTripPlan; import org.opentripplanner.model.plan.TripPlan; public class TripPlanMapper { diff --git a/src/main/java/org/opentripplanner/api/mapping/TripSearchMetadataMapper.java b/src/ext/java/org/opentripplanner/ext/restapi/mapping/TripSearchMetadataMapper.java similarity index 85% rename from src/main/java/org/opentripplanner/api/mapping/TripSearchMetadataMapper.java rename to src/ext/java/org/opentripplanner/ext/restapi/mapping/TripSearchMetadataMapper.java index 0a3b46bb118..db92e821493 100644 --- a/src/main/java/org/opentripplanner/api/mapping/TripSearchMetadataMapper.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/mapping/TripSearchMetadataMapper.java @@ -1,7 +1,7 @@ -package org.opentripplanner.api.mapping; +package org.opentripplanner.ext.restapi.mapping; import java.time.Instant; -import org.opentripplanner.api.model.ApiTripSearchMetadata; +import org.opentripplanner.ext.restapi.model.ApiTripSearchMetadata; import org.opentripplanner.routing.api.response.TripSearchMetadata; public class TripSearchMetadataMapper { diff --git a/src/main/java/org/opentripplanner/api/mapping/TripTimeMapper.java b/src/ext/java/org/opentripplanner/ext/restapi/mapping/TripTimeMapper.java similarity index 86% rename from src/main/java/org/opentripplanner/api/mapping/TripTimeMapper.java rename to src/ext/java/org/opentripplanner/ext/restapi/mapping/TripTimeMapper.java index 2f5bfe91026..f1f37e6d8b4 100644 --- a/src/main/java/org/opentripplanner/api/mapping/TripTimeMapper.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/mapping/TripTimeMapper.java @@ -1,10 +1,11 @@ -package org.opentripplanner.api.mapping; +package org.opentripplanner.ext.restapi.mapping; import java.util.Collection; import java.util.List; import java.util.stream.Collectors; -import org.opentripplanner.api.model.ApiRealTimeState; -import org.opentripplanner.api.model.ApiTripTimeShort; +import org.opentripplanner.ext.restapi.model.ApiRealTimeState; +import org.opentripplanner.ext.restapi.model.ApiTripTimeShort; +import org.opentripplanner.framework.i18n.I18NStringMapper; import org.opentripplanner.model.TripTimeOnDate; public class TripTimeMapper { diff --git a/src/main/java/org/opentripplanner/api/mapping/VehicleRentalStationMapper.java b/src/ext/java/org/opentripplanner/ext/restapi/mapping/VehicleRentalStationMapper.java similarity index 88% rename from src/main/java/org/opentripplanner/api/mapping/VehicleRentalStationMapper.java rename to src/ext/java/org/opentripplanner/ext/restapi/mapping/VehicleRentalStationMapper.java index 482a966dec0..2f68448fdf4 100644 --- a/src/main/java/org/opentripplanner/api/mapping/VehicleRentalStationMapper.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/mapping/VehicleRentalStationMapper.java @@ -1,8 +1,8 @@ -package org.opentripplanner.api.mapping; +package org.opentripplanner.ext.restapi.mapping; import java.util.List; import java.util.Locale; -import org.opentripplanner.api.model.ApiVehicleRentalStation; +import org.opentripplanner.ext.restapi.model.ApiVehicleRentalStation; import org.opentripplanner.service.vehiclerental.model.VehicleRentalPlace; public class VehicleRentalStationMapper { diff --git a/src/main/java/org/opentripplanner/api/mapping/VertexTypeMapper.java b/src/ext/java/org/opentripplanner/ext/restapi/mapping/VertexTypeMapper.java similarity index 83% rename from src/main/java/org/opentripplanner/api/mapping/VertexTypeMapper.java rename to src/ext/java/org/opentripplanner/ext/restapi/mapping/VertexTypeMapper.java index 340be3d60fd..5f59ea4fd57 100644 --- a/src/main/java/org/opentripplanner/api/mapping/VertexTypeMapper.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/mapping/VertexTypeMapper.java @@ -1,6 +1,6 @@ -package org.opentripplanner.api.mapping; +package org.opentripplanner.ext.restapi.mapping; -import org.opentripplanner.api.model.ApiVertexType; +import org.opentripplanner.ext.restapi.model.ApiVertexType; import org.opentripplanner.model.plan.VertexType; public class VertexTypeMapper { diff --git a/src/main/java/org/opentripplanner/api/mapping/WalkStepMapper.java b/src/ext/java/org/opentripplanner/ext/restapi/mapping/WalkStepMapper.java similarity index 76% rename from src/main/java/org/opentripplanner/api/mapping/WalkStepMapper.java rename to src/ext/java/org/opentripplanner/ext/restapi/mapping/WalkStepMapper.java index 5d633079e4a..c5c59e4dc37 100644 --- a/src/main/java/org/opentripplanner/api/mapping/WalkStepMapper.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/mapping/WalkStepMapper.java @@ -1,23 +1,24 @@ -package org.opentripplanner.api.mapping; +package org.opentripplanner.ext.restapi.mapping; -import static org.opentripplanner.api.mapping.ElevationMapper.mapElevation; -import static org.opentripplanner.api.mapping.RelativeDirectionMapper.mapRelativeDirection; +import static org.opentripplanner.ext.restapi.mapping.ElevationMapper.mapElevation; +import static org.opentripplanner.ext.restapi.mapping.RelativeDirectionMapper.mapRelativeDirection; import java.util.Collection; import java.util.List; import java.util.Locale; import java.util.stream.Collectors; -import org.opentripplanner.api.model.ApiWalkStep; +import org.opentripplanner.apis.support.mapping.StreetNoteMapper; +import org.opentripplanner.ext.restapi.model.ApiWalkStep; import org.opentripplanner.model.plan.WalkStep; public class WalkStepMapper { - private final StreetNoteMaperMapper alertsMapper; + private final StreetNoteMapper alertsMapper; private final Locale locale; public WalkStepMapper(Locale locale) { this.locale = locale; - this.alertsMapper = new StreetNoteMaperMapper(locale); + this.alertsMapper = new StreetNoteMapper(locale); } public List mapWalkSteps(Collection domain) { diff --git a/src/main/java/org/opentripplanner/api/mapping/WheelchairAccessibilityMapper.java b/src/ext/java/org/opentripplanner/ext/restapi/mapping/WheelchairAccessibilityMapper.java similarity index 87% rename from src/main/java/org/opentripplanner/api/mapping/WheelchairAccessibilityMapper.java rename to src/ext/java/org/opentripplanner/ext/restapi/mapping/WheelchairAccessibilityMapper.java index 05d8cc97959..e0aafeaee05 100644 --- a/src/main/java/org/opentripplanner/api/mapping/WheelchairAccessibilityMapper.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/mapping/WheelchairAccessibilityMapper.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.mapping; +package org.opentripplanner.ext.restapi.mapping; import org.opentripplanner.transit.model.basic.Accessibility; diff --git a/src/main/java/org/opentripplanner/api/model/ApiAbsoluteDirection.java b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiAbsoluteDirection.java similarity index 79% rename from src/main/java/org/opentripplanner/api/model/ApiAbsoluteDirection.java rename to src/ext/java/org/opentripplanner/ext/restapi/model/ApiAbsoluteDirection.java index 48d93618bf7..ffa00cbc54e 100644 --- a/src/main/java/org/opentripplanner/api/model/ApiAbsoluteDirection.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiAbsoluteDirection.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.model; +package org.opentripplanner.ext.restapi.model; /** * An absolute cardinal or intermediate direction. diff --git a/src/main/java/org/opentripplanner/api/model/ApiAgency.java b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiAgency.java similarity index 93% rename from src/main/java/org/opentripplanner/api/model/ApiAgency.java rename to src/ext/java/org/opentripplanner/ext/restapi/model/ApiAgency.java index e895ea655cd..ada6739a795 100644 --- a/src/main/java/org/opentripplanner/api/model/ApiAgency.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiAgency.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.model; +package org.opentripplanner.ext.restapi.model; import java.io.Serializable; import java.util.Objects; diff --git a/src/main/java/org/opentripplanner/api/model/ApiAlert.java b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiAlert.java similarity index 83% rename from src/main/java/org/opentripplanner/api/model/ApiAlert.java rename to src/ext/java/org/opentripplanner/ext/restapi/model/ApiAlert.java index 3c4d77c6129..a503a7d18e2 100644 --- a/src/main/java/org/opentripplanner/api/model/ApiAlert.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiAlert.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.model; +package org.opentripplanner.ext.restapi.model; import java.util.Date; diff --git a/src/main/java/org/opentripplanner/api/model/ApiBookingInfo.java b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiBookingInfo.java similarity index 98% rename from src/main/java/org/opentripplanner/api/model/ApiBookingInfo.java rename to src/ext/java/org/opentripplanner/ext/restapi/model/ApiBookingInfo.java index f3a553fc1f1..c89d6429caa 100644 --- a/src/main/java/org/opentripplanner/api/model/ApiBookingInfo.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiBookingInfo.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.model; +package org.opentripplanner.ext.restapi.model; import java.io.Serializable; import java.time.Duration; diff --git a/src/main/java/org/opentripplanner/api/model/ApiBookingTime.java b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiBookingTime.java similarity index 94% rename from src/main/java/org/opentripplanner/api/model/ApiBookingTime.java rename to src/ext/java/org/opentripplanner/ext/restapi/model/ApiBookingTime.java index e0c140f8ee1..08eee69a3cf 100644 --- a/src/main/java/org/opentripplanner/api/model/ApiBookingTime.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiBookingTime.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.model; +package org.opentripplanner.ext.restapi.model; import java.io.Serializable; import org.opentripplanner.framework.tostring.ToStringBuilder; diff --git a/src/main/java/org/opentripplanner/api/model/ApiContactInfo.java b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiContactInfo.java similarity index 97% rename from src/main/java/org/opentripplanner/api/model/ApiContactInfo.java rename to src/ext/java/org/opentripplanner/ext/restapi/model/ApiContactInfo.java index 06c1fc8d198..b7c2ec90166 100644 --- a/src/main/java/org/opentripplanner/api/model/ApiContactInfo.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiContactInfo.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.model; +package org.opentripplanner.ext.restapi.model; import java.io.Serializable; import org.opentripplanner.framework.tostring.ToStringBuilder; diff --git a/src/main/java/org/opentripplanner/api/model/ApiCurrency.java b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiCurrency.java similarity index 71% rename from src/main/java/org/opentripplanner/api/model/ApiCurrency.java rename to src/ext/java/org/opentripplanner/ext/restapi/model/ApiCurrency.java index 3835f7986ca..b3cff1eaa93 100644 --- a/src/main/java/org/opentripplanner/api/model/ApiCurrency.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiCurrency.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.model; +package org.opentripplanner.ext.restapi.model; public record ApiCurrency( String currency, diff --git a/src/main/java/org/opentripplanner/api/model/ApiFareComponent.java b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiFareComponent.java similarity index 76% rename from src/main/java/org/opentripplanner/api/model/ApiFareComponent.java rename to src/ext/java/org/opentripplanner/ext/restapi/model/ApiFareComponent.java index 8d6038c487a..e26f859c4f2 100644 --- a/src/main/java/org/opentripplanner/api/model/ApiFareComponent.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiFareComponent.java @@ -1,7 +1,6 @@ -package org.opentripplanner.api.model; +package org.opentripplanner.ext.restapi.model; import java.util.List; -import java.util.Optional; import org.opentripplanner.transit.model.framework.FeedScopedId; public record ApiFareComponent( diff --git a/src/main/java/org/opentripplanner/api/model/ApiFareProduct.java b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiFareProduct.java similarity index 91% rename from src/main/java/org/opentripplanner/api/model/ApiFareProduct.java rename to src/ext/java/org/opentripplanner/ext/restapi/model/ApiFareProduct.java index 2beb991855d..af8561b73cb 100644 --- a/src/main/java/org/opentripplanner/api/model/ApiFareProduct.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiFareProduct.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.model; +package org.opentripplanner.ext.restapi.model; /** * A Fares V2 product. This is a type of ticket or monthly pass that customers can buy. diff --git a/src/main/java/org/opentripplanner/api/model/ApiFareQualifier.java b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiFareQualifier.java similarity index 83% rename from src/main/java/org/opentripplanner/api/model/ApiFareQualifier.java rename to src/ext/java/org/opentripplanner/ext/restapi/model/ApiFareQualifier.java index 702caca7a0f..94a3731863a 100644 --- a/src/main/java/org/opentripplanner/api/model/ApiFareQualifier.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiFareQualifier.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.model; +package org.opentripplanner.ext.restapi.model; /** * Qualifiers for Fares V2 fare products. Qualifiers can be rider categories (youth, senior, veteran) or diff --git a/src/main/java/org/opentripplanner/api/model/ApiFeedInfo.java b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiFeedInfo.java similarity index 93% rename from src/main/java/org/opentripplanner/api/model/ApiFeedInfo.java rename to src/ext/java/org/opentripplanner/ext/restapi/model/ApiFeedInfo.java index a1614ba6391..1b96ee0759d 100644 --- a/src/main/java/org/opentripplanner/api/model/ApiFeedInfo.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiFeedInfo.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.model; +package org.opentripplanner.ext.restapi.model; import java.io.Serializable; import java.util.Objects; diff --git a/src/main/java/org/opentripplanner/api/model/ApiItinerary.java b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiItinerary.java similarity index 98% rename from src/main/java/org/opentripplanner/api/model/ApiItinerary.java rename to src/ext/java/org/opentripplanner/ext/restapi/model/ApiItinerary.java index e2d205de13e..0bce9426fd8 100644 --- a/src/main/java/org/opentripplanner/api/model/ApiItinerary.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiItinerary.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.model; +package org.opentripplanner.ext.restapi.model; import java.util.ArrayList; import java.util.Calendar; diff --git a/src/main/java/org/opentripplanner/api/model/ApiItineraryFares.java b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiItineraryFares.java similarity index 92% rename from src/main/java/org/opentripplanner/api/model/ApiItineraryFares.java rename to src/ext/java/org/opentripplanner/ext/restapi/model/ApiItineraryFares.java index e908a81b452..a7140e59d4d 100644 --- a/src/main/java/org/opentripplanner/api/model/ApiItineraryFares.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiItineraryFares.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.model; +package org.opentripplanner.ext.restapi.model; import java.util.List; import java.util.Map; diff --git a/src/main/java/org/opentripplanner/api/model/ApiLeg.java b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiLeg.java similarity index 99% rename from src/main/java/org/opentripplanner/api/model/ApiLeg.java rename to src/ext/java/org/opentripplanner/ext/restapi/model/ApiLeg.java index 87be725615d..7bbd83f7c2d 100644 --- a/src/main/java/org/opentripplanner/api/model/ApiLeg.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiLeg.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.model; +package org.opentripplanner.ext.restapi.model; import java.util.Calendar; import java.util.List; diff --git a/src/main/java/org/opentripplanner/api/model/ApiLegProducts.java b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiLegProducts.java similarity index 88% rename from src/main/java/org/opentripplanner/api/model/ApiLegProducts.java rename to src/ext/java/org/opentripplanner/ext/restapi/model/ApiLegProducts.java index ef7d95a3abf..abd4643100b 100644 --- a/src/main/java/org/opentripplanner/api/model/ApiLegProducts.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiLegProducts.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.model; +package org.opentripplanner.ext.restapi.model; import java.util.Collection; import java.util.List; diff --git a/src/main/java/org/opentripplanner/api/model/ApiMoney.java b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiMoney.java similarity index 56% rename from src/main/java/org/opentripplanner/api/model/ApiMoney.java rename to src/ext/java/org/opentripplanner/ext/restapi/model/ApiMoney.java index a9a27e828ae..a5f3f840bf6 100644 --- a/src/main/java/org/opentripplanner/api/model/ApiMoney.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiMoney.java @@ -1,3 +1,3 @@ -package org.opentripplanner.api.model; +package org.opentripplanner.ext.restapi.model; public record ApiMoney(int cents, ApiCurrency currency) {} diff --git a/src/main/java/org/opentripplanner/api/model/ApiPatternDetail.java b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiPatternDetail.java similarity index 87% rename from src/main/java/org/opentripplanner/api/model/ApiPatternDetail.java rename to src/ext/java/org/opentripplanner/ext/restapi/model/ApiPatternDetail.java index 1acb3acb6d5..d24f7f35c12 100644 --- a/src/main/java/org/opentripplanner/api/model/ApiPatternDetail.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiPatternDetail.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.model; +package org.opentripplanner.ext.restapi.model; import java.util.ArrayList; import java.util.Collection; diff --git a/src/main/java/org/opentripplanner/api/model/ApiPatternShort.java b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiPatternShort.java similarity index 68% rename from src/main/java/org/opentripplanner/api/model/ApiPatternShort.java rename to src/ext/java/org/opentripplanner/ext/restapi/model/ApiPatternShort.java index 0adcb6c2f18..d2acd234f47 100644 --- a/src/main/java/org/opentripplanner/api/model/ApiPatternShort.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiPatternShort.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.model; +package org.opentripplanner.ext.restapi.model; public class ApiPatternShort { diff --git a/src/main/java/org/opentripplanner/api/model/ApiPlace.java b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiPlace.java similarity index 97% rename from src/main/java/org/opentripplanner/api/model/ApiPlace.java rename to src/ext/java/org/opentripplanner/ext/restapi/model/ApiPlace.java index 3ac922059ee..7cfe3bc7c22 100644 --- a/src/main/java/org/opentripplanner/api/model/ApiPlace.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiPlace.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.model; +package org.opentripplanner.ext.restapi.model; import java.util.Calendar; import java.util.List; diff --git a/src/main/java/org/opentripplanner/api/model/ApiRealTimeState.java b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiRealTimeState.java similarity index 96% rename from src/main/java/org/opentripplanner/api/model/ApiRealTimeState.java rename to src/ext/java/org/opentripplanner/ext/restapi/model/ApiRealTimeState.java index df307007157..d9a068349ec 100644 --- a/src/main/java/org/opentripplanner/api/model/ApiRealTimeState.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiRealTimeState.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.model; +package org.opentripplanner.ext.restapi.model; import org.opentripplanner.transit.model.timetable.RealTimeState; diff --git a/src/main/java/org/opentripplanner/api/model/ApiRelativeDirection.java b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiRelativeDirection.java similarity index 90% rename from src/main/java/org/opentripplanner/api/model/ApiRelativeDirection.java rename to src/ext/java/org/opentripplanner/ext/restapi/model/ApiRelativeDirection.java index e8e1553d51f..02a530f06de 100644 --- a/src/main/java/org/opentripplanner/api/model/ApiRelativeDirection.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiRelativeDirection.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.model; +package org.opentripplanner.ext.restapi.model; /** * Represents a turn direction, relative to the current heading. diff --git a/src/main/java/org/opentripplanner/api/model/ApiRoute.java b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiRoute.java similarity index 95% rename from src/main/java/org/opentripplanner/api/model/ApiRoute.java rename to src/ext/java/org/opentripplanner/ext/restapi/model/ApiRoute.java index 1826091f210..d4ce90d9b23 100644 --- a/src/main/java/org/opentripplanner/api/model/ApiRoute.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiRoute.java @@ -1,5 +1,5 @@ /* This file is based on code copied from project OneBusAway, see the LICENSE file for further information. */ -package org.opentripplanner.api.model; +package org.opentripplanner.ext.restapi.model; import java.io.Serializable; import java.util.Objects; diff --git a/src/main/java/org/opentripplanner/api/model/ApiRouteShort.java b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiRouteShort.java similarity index 85% rename from src/main/java/org/opentripplanner/api/model/ApiRouteShort.java rename to src/ext/java/org/opentripplanner/ext/restapi/model/ApiRouteShort.java index db74e2514cc..a62dcc4bdb6 100644 --- a/src/main/java/org/opentripplanner/api/model/ApiRouteShort.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiRouteShort.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.model; +package org.opentripplanner.ext.restapi.model; public class ApiRouteShort { diff --git a/src/main/java/org/opentripplanner/api/model/ApiRouterInfo.java b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiRouterInfo.java similarity index 97% rename from src/main/java/org/opentripplanner/api/model/ApiRouterInfo.java rename to src/ext/java/org/opentripplanner/ext/restapi/model/ApiRouterInfo.java index 3c08defcba5..a0bbb1116b3 100644 --- a/src/main/java/org/opentripplanner/api/model/ApiRouterInfo.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiRouterInfo.java @@ -1,9 +1,9 @@ -package org.opentripplanner.api.model; +package org.opentripplanner.ext.restapi.model; import java.util.Date; import java.util.List; import org.locationtech.jts.geom.Geometry; -import org.opentripplanner.api.mapping.ModeMapper; +import org.opentripplanner.ext.restapi.mapping.ModeMapper; import org.opentripplanner.routing.graph.Graph; import org.opentripplanner.routing.vehicle_parking.VehicleParkingService; import org.opentripplanner.service.vehiclerental.VehicleRentalService; diff --git a/src/main/java/org/opentripplanner/api/model/ApiRouterList.java b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiRouterList.java similarity index 75% rename from src/main/java/org/opentripplanner/api/model/ApiRouterList.java rename to src/ext/java/org/opentripplanner/ext/restapi/model/ApiRouterList.java index ec412716202..dd7ef3544af 100644 --- a/src/main/java/org/opentripplanner/api/model/ApiRouterList.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiRouterList.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.model; +package org.opentripplanner.ext.restapi.model; import java.util.ArrayList; import java.util.List; diff --git a/src/main/java/org/opentripplanner/api/model/ApiStop.java b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiStop.java similarity index 96% rename from src/main/java/org/opentripplanner/api/model/ApiStop.java rename to src/ext/java/org/opentripplanner/ext/restapi/model/ApiStop.java index b2604268f76..abe4adb623a 100644 --- a/src/main/java/org/opentripplanner/api/model/ApiStop.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiStop.java @@ -1,5 +1,5 @@ /* This file is based on code copied from project OneBusAway, see the LICENSE file for further information. */ -package org.opentripplanner.api.model; +package org.opentripplanner.ext.restapi.model; import java.io.Serializable; import java.util.Objects; diff --git a/src/main/java/org/opentripplanner/api/model/ApiStopShort.java b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiStopShort.java similarity index 92% rename from src/main/java/org/opentripplanner/api/model/ApiStopShort.java rename to src/ext/java/org/opentripplanner/ext/restapi/model/ApiStopShort.java index 3fe4daf7c4c..1eafd760248 100644 --- a/src/main/java/org/opentripplanner/api/model/ApiStopShort.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiStopShort.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.model; +package org.opentripplanner.ext.restapi.model; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; diff --git a/src/main/java/org/opentripplanner/api/model/ApiStopTimesInPattern.java b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiStopTimesInPattern.java similarity index 74% rename from src/main/java/org/opentripplanner/api/model/ApiStopTimesInPattern.java rename to src/ext/java/org/opentripplanner/ext/restapi/model/ApiStopTimesInPattern.java index c0069c1662a..405c200651b 100644 --- a/src/main/java/org/opentripplanner/api/model/ApiStopTimesInPattern.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiStopTimesInPattern.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.model; +package org.opentripplanner.ext.restapi.model; import java.util.List; diff --git a/src/main/java/org/opentripplanner/api/model/ApiSystemNotice.java b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiSystemNotice.java similarity index 95% rename from src/main/java/org/opentripplanner/api/model/ApiSystemNotice.java rename to src/ext/java/org/opentripplanner/ext/restapi/model/ApiSystemNotice.java index ab95bc2034d..dc7eb51177e 100644 --- a/src/main/java/org/opentripplanner/api/model/ApiSystemNotice.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiSystemNotice.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.model; +package org.opentripplanner.ext.restapi.model; import org.opentripplanner.routing.alertpatch.TransitAlert; import org.opentripplanner.transit.model.basic.Notice; diff --git a/src/main/java/org/opentripplanner/api/model/ApiTransfer.java b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiTransfer.java similarity index 82% rename from src/main/java/org/opentripplanner/api/model/ApiTransfer.java rename to src/ext/java/org/opentripplanner/ext/restapi/model/ApiTransfer.java index a9d45aac4c1..38cede8c1f1 100644 --- a/src/main/java/org/opentripplanner/api/model/ApiTransfer.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiTransfer.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.model; +package org.opentripplanner.ext.restapi.model; /** Represents a transfer from a stop */ public class ApiTransfer { diff --git a/src/main/java/org/opentripplanner/api/model/ApiTravelOption.java b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiTravelOption.java similarity index 97% rename from src/main/java/org/opentripplanner/api/model/ApiTravelOption.java rename to src/ext/java/org/opentripplanner/ext/restapi/model/ApiTravelOption.java index 06b186969b0..d09de672d91 100644 --- a/src/main/java/org/opentripplanner/api/model/ApiTravelOption.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiTravelOption.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.model; +package org.opentripplanner.ext.restapi.model; import java.util.HashSet; import java.util.Objects; diff --git a/src/main/java/org/opentripplanner/api/model/ApiTravelOptionsMaker.java b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiTravelOptionsMaker.java similarity index 98% rename from src/main/java/org/opentripplanner/api/model/ApiTravelOptionsMaker.java rename to src/ext/java/org/opentripplanner/ext/restapi/model/ApiTravelOptionsMaker.java index 5c0109f8baf..cf424392d70 100644 --- a/src/main/java/org/opentripplanner/api/model/ApiTravelOptionsMaker.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiTravelOptionsMaker.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.model; +package org.opentripplanner.ext.restapi.model; import java.util.ArrayList; import java.util.List; diff --git a/src/main/java/org/opentripplanner/api/model/ApiTrip.java b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiTrip.java similarity index 96% rename from src/main/java/org/opentripplanner/api/model/ApiTrip.java rename to src/ext/java/org/opentripplanner/ext/restapi/model/ApiTrip.java index 947991ac392..3ff0626c9a8 100644 --- a/src/main/java/org/opentripplanner/api/model/ApiTrip.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiTrip.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.model; +package org.opentripplanner.ext.restapi.model; import java.io.Serializable; import java.util.Objects; diff --git a/src/main/java/org/opentripplanner/api/model/ApiTripPlan.java b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiTripPlan.java similarity index 90% rename from src/main/java/org/opentripplanner/api/model/ApiTripPlan.java rename to src/ext/java/org/opentripplanner/ext/restapi/model/ApiTripPlan.java index 7c62b6cdd66..bfb812b69c3 100644 --- a/src/main/java/org/opentripplanner/api/model/ApiTripPlan.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiTripPlan.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.model; +package org.opentripplanner.ext.restapi.model; import java.util.ArrayList; import java.util.Date; diff --git a/src/main/java/org/opentripplanner/api/model/ApiTripSearchMetadata.java b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiTripSearchMetadata.java similarity index 98% rename from src/main/java/org/opentripplanner/api/model/ApiTripSearchMetadata.java rename to src/ext/java/org/opentripplanner/ext/restapi/model/ApiTripSearchMetadata.java index 486118883f9..abe5a74337f 100644 --- a/src/main/java/org/opentripplanner/api/model/ApiTripSearchMetadata.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiTripSearchMetadata.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.model; +package org.opentripplanner.ext.restapi.model; /** * Meta-data about the trip search performed. diff --git a/src/main/java/org/opentripplanner/api/model/ApiTripShort.java b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiTripShort.java similarity index 77% rename from src/main/java/org/opentripplanner/api/model/ApiTripShort.java rename to src/ext/java/org/opentripplanner/ext/restapi/model/ApiTripShort.java index 17560af64ce..cedfa471d4a 100644 --- a/src/main/java/org/opentripplanner/api/model/ApiTripShort.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiTripShort.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.model; +package org.opentripplanner.ext.restapi.model; public class ApiTripShort { diff --git a/src/main/java/org/opentripplanner/api/model/ApiTripTimeShort.java b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiTripTimeShort.java similarity index 93% rename from src/main/java/org/opentripplanner/api/model/ApiTripTimeShort.java rename to src/ext/java/org/opentripplanner/ext/restapi/model/ApiTripTimeShort.java index 0a340d4a812..21c6010c5a2 100644 --- a/src/main/java/org/opentripplanner/api/model/ApiTripTimeShort.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiTripTimeShort.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.model; +package org.opentripplanner.ext.restapi.model; import java.io.Serializable; diff --git a/src/main/java/org/opentripplanner/api/model/ApiVehicleParkingSpaces.java b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiVehicleParkingSpaces.java similarity index 97% rename from src/main/java/org/opentripplanner/api/model/ApiVehicleParkingSpaces.java rename to src/ext/java/org/opentripplanner/ext/restapi/model/ApiVehicleParkingSpaces.java index 8c4ab4b8fee..bcb10e70f0f 100644 --- a/src/main/java/org/opentripplanner/api/model/ApiVehicleParkingSpaces.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiVehicleParkingSpaces.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.model; +package org.opentripplanner.ext.restapi.model; public class ApiVehicleParkingSpaces { diff --git a/src/main/java/org/opentripplanner/api/model/ApiVehicleParkingWithEntrance.java b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiVehicleParkingWithEntrance.java similarity index 99% rename from src/main/java/org/opentripplanner/api/model/ApiVehicleParkingWithEntrance.java rename to src/ext/java/org/opentripplanner/ext/restapi/model/ApiVehicleParkingWithEntrance.java index 8cac78f6c9e..68a9f37dfe4 100644 --- a/src/main/java/org/opentripplanner/api/model/ApiVehicleParkingWithEntrance.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiVehicleParkingWithEntrance.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.model; +package org.opentripplanner.ext.restapi.model; import java.util.List; diff --git a/src/main/java/org/opentripplanner/api/model/ApiVehicleRentalStation.java b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiVehicleRentalStation.java similarity index 95% rename from src/main/java/org/opentripplanner/api/model/ApiVehicleRentalStation.java rename to src/ext/java/org/opentripplanner/ext/restapi/model/ApiVehicleRentalStation.java index 354961bae16..8431ac5c387 100644 --- a/src/main/java/org/opentripplanner/api/model/ApiVehicleRentalStation.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiVehicleRentalStation.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.model; +package org.opentripplanner.ext.restapi.model; import java.util.List; import org.opentripplanner.service.vehiclerental.model.VehicleRentalStationUris; diff --git a/src/main/java/org/opentripplanner/api/model/ApiVehicleRentalStationList.java b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiVehicleRentalStationList.java similarity index 78% rename from src/main/java/org/opentripplanner/api/model/ApiVehicleRentalStationList.java rename to src/ext/java/org/opentripplanner/ext/restapi/model/ApiVehicleRentalStationList.java index ed74f8a7ab7..c97a18c337e 100644 --- a/src/main/java/org/opentripplanner/api/model/ApiVehicleRentalStationList.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiVehicleRentalStationList.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.model; +package org.opentripplanner.ext.restapi.model; import java.util.ArrayList; import java.util.List; diff --git a/src/main/java/org/opentripplanner/api/model/ApiVertexType.java b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiVertexType.java similarity index 81% rename from src/main/java/org/opentripplanner/api/model/ApiVertexType.java rename to src/ext/java/org/opentripplanner/ext/restapi/model/ApiVertexType.java index 3bcc4034272..595f0628e0a 100644 --- a/src/main/java/org/opentripplanner/api/model/ApiVertexType.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiVertexType.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.model; +package org.opentripplanner.ext.restapi.model; /** * Represent type of vertex, used in Place aka from, to in API for easier client side localization diff --git a/src/main/java/org/opentripplanner/api/model/ApiWalkStep.java b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiWalkStep.java similarity index 98% rename from src/main/java/org/opentripplanner/api/model/ApiWalkStep.java rename to src/ext/java/org/opentripplanner/ext/restapi/model/ApiWalkStep.java index 5e810d98602..363a01cb7b5 100644 --- a/src/main/java/org/opentripplanner/api/model/ApiWalkStep.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiWalkStep.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.model; +package org.opentripplanner.ext.restapi.model; import java.util.List; diff --git a/src/main/java/org/opentripplanner/api/resource/ElevationMetadata.java b/src/ext/java/org/opentripplanner/ext/restapi/model/ElevationMetadata.java similarity index 83% rename from src/main/java/org/opentripplanner/api/resource/ElevationMetadata.java rename to src/ext/java/org/opentripplanner/ext/restapi/model/ElevationMetadata.java index 7b11f5fa736..b885883b17e 100644 --- a/src/main/java/org/opentripplanner/api/resource/ElevationMetadata.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/model/ElevationMetadata.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.resource; +package org.opentripplanner.ext.restapi.model; /** * Contains elevation-specific metadata to be included in the response diff --git a/src/main/java/org/opentripplanner/api/resource/TripPlannerResponse.java b/src/ext/java/org/opentripplanner/ext/restapi/model/TripPlannerResponse.java similarity index 94% rename from src/main/java/org/opentripplanner/api/resource/TripPlannerResponse.java rename to src/ext/java/org/opentripplanner/ext/restapi/model/TripPlannerResponse.java index 970acad5ac2..28cce2dd669 100644 --- a/src/main/java/org/opentripplanner/api/resource/TripPlannerResponse.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/model/TripPlannerResponse.java @@ -1,12 +1,11 @@ -package org.opentripplanner.api.resource; +package org.opentripplanner.ext.restapi.model; import jakarta.ws.rs.core.UriInfo; import java.util.HashMap; import java.util.List; import java.util.Map.Entry; -import org.opentripplanner.api.model.ApiTripPlan; -import org.opentripplanner.api.model.ApiTripSearchMetadata; -import org.opentripplanner.api.model.error.PlannerError; +import org.opentripplanner.api.error.PlannerError; +import org.opentripplanner.api.resource.DebugOutput; /** Represents a trip planner response, will be serialized into XML or JSON by Jersey */ public class TripPlannerResponse { diff --git a/src/main/java/org/opentripplanner/api/resource/BikeRental.java b/src/ext/java/org/opentripplanner/ext/restapi/resources/BikeRental.java similarity index 91% rename from src/main/java/org/opentripplanner/api/resource/BikeRental.java rename to src/ext/java/org/opentripplanner/ext/restapi/resources/BikeRental.java index fdac9b39023..0da598f8a3f 100644 --- a/src/main/java/org/opentripplanner/api/resource/BikeRental.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/resources/BikeRental.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.resource; +package org.opentripplanner.ext.restapi.resources; import jakarta.ws.rs.GET; import jakarta.ws.rs.Path; @@ -12,9 +12,9 @@ import java.util.List; import java.util.Locale; import org.locationtech.jts.geom.Envelope; -import org.opentripplanner.api.mapping.VehicleRentalStationMapper; -import org.opentripplanner.api.model.ApiVehicleRentalStation; -import org.opentripplanner.api.model.ApiVehicleRentalStationList; +import org.opentripplanner.ext.restapi.mapping.VehicleRentalStationMapper; +import org.opentripplanner.ext.restapi.model.ApiVehicleRentalStation; +import org.opentripplanner.ext.restapi.model.ApiVehicleRentalStationList; import org.opentripplanner.service.vehiclerental.VehicleRentalService; import org.opentripplanner.service.vehiclerental.model.VehicleRentalPlace; import org.opentripplanner.standalone.api.OtpServerRequestContext; diff --git a/src/main/java/org/opentripplanner/index/IndexAPI.java b/src/ext/java/org/opentripplanner/ext/restapi/resources/IndexAPI.java similarity index 93% rename from src/main/java/org/opentripplanner/index/IndexAPI.java rename to src/ext/java/org/opentripplanner/ext/restapi/resources/IndexAPI.java index 74eba3a60b8..5bdda8a57a2 100644 --- a/src/main/java/org/opentripplanner/index/IndexAPI.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/resources/IndexAPI.java @@ -1,4 +1,4 @@ -package org.opentripplanner.index; +package org.opentripplanner.ext.restapi.resources; import jakarta.ws.rs.BadRequestException; import jakarta.ws.rs.DefaultValue; @@ -25,31 +25,31 @@ import java.util.stream.Collectors; import org.locationtech.jts.geom.Coordinate; import org.locationtech.jts.geom.Envelope; -import org.opentripplanner.api.mapping.AgencyMapper; -import org.opentripplanner.api.mapping.AlertMapper; -import org.opentripplanner.api.mapping.FeedInfoMapper; -import org.opentripplanner.api.mapping.FeedScopedIdMapper; -import org.opentripplanner.api.mapping.RouteMapper; -import org.opentripplanner.api.mapping.StopMapper; -import org.opentripplanner.api.mapping.StopTimesInPatternMapper; -import org.opentripplanner.api.mapping.TransferMapper; -import org.opentripplanner.api.mapping.TripMapper; -import org.opentripplanner.api.mapping.TripPatternMapper; -import org.opentripplanner.api.mapping.TripTimeMapper; -import org.opentripplanner.api.model.ApiAgency; -import org.opentripplanner.api.model.ApiAlert; -import org.opentripplanner.api.model.ApiFeedInfo; -import org.opentripplanner.api.model.ApiPatternShort; -import org.opentripplanner.api.model.ApiRoute; -import org.opentripplanner.api.model.ApiRouteShort; -import org.opentripplanner.api.model.ApiStop; -import org.opentripplanner.api.model.ApiStopShort; -import org.opentripplanner.api.model.ApiStopTimesInPattern; -import org.opentripplanner.api.model.ApiTransfer; -import org.opentripplanner.api.model.ApiTrip; -import org.opentripplanner.api.model.ApiTripShort; -import org.opentripplanner.api.model.ApiTripTimeShort; -import org.opentripplanner.api.support.SemanticHash; +import org.opentripplanner.apis.support.SemanticHash; +import org.opentripplanner.ext.restapi.mapping.AgencyMapper; +import org.opentripplanner.ext.restapi.mapping.AlertMapper; +import org.opentripplanner.ext.restapi.mapping.FeedInfoMapper; +import org.opentripplanner.ext.restapi.mapping.FeedScopedIdMapper; +import org.opentripplanner.ext.restapi.mapping.RouteMapper; +import org.opentripplanner.ext.restapi.mapping.StopMapper; +import org.opentripplanner.ext.restapi.mapping.StopTimesInPatternMapper; +import org.opentripplanner.ext.restapi.mapping.TransferMapper; +import org.opentripplanner.ext.restapi.mapping.TripMapper; +import org.opentripplanner.ext.restapi.mapping.TripPatternMapper; +import org.opentripplanner.ext.restapi.mapping.TripTimeMapper; +import org.opentripplanner.ext.restapi.model.ApiAgency; +import org.opentripplanner.ext.restapi.model.ApiAlert; +import org.opentripplanner.ext.restapi.model.ApiFeedInfo; +import org.opentripplanner.ext.restapi.model.ApiPatternShort; +import org.opentripplanner.ext.restapi.model.ApiRoute; +import org.opentripplanner.ext.restapi.model.ApiRouteShort; +import org.opentripplanner.ext.restapi.model.ApiStop; +import org.opentripplanner.ext.restapi.model.ApiStopShort; +import org.opentripplanner.ext.restapi.model.ApiStopTimesInPattern; +import org.opentripplanner.ext.restapi.model.ApiTransfer; +import org.opentripplanner.ext.restapi.model.ApiTrip; +import org.opentripplanner.ext.restapi.model.ApiTripShort; +import org.opentripplanner.ext.restapi.model.ApiTripTimeShort; import org.opentripplanner.framework.geometry.EncodedPolyline; import org.opentripplanner.framework.time.ServiceDateUtils; import org.opentripplanner.model.StopTimesInPattern; diff --git a/src/main/java/org/opentripplanner/api/resource/PlannerResource.java b/src/ext/java/org/opentripplanner/ext/restapi/resources/PlannerResource.java similarity index 92% rename from src/main/java/org/opentripplanner/api/resource/PlannerResource.java rename to src/ext/java/org/opentripplanner/ext/restapi/resources/PlannerResource.java index bb2b4f1020a..38c70851b76 100644 --- a/src/main/java/org/opentripplanner/api/resource/PlannerResource.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/resources/PlannerResource.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.resource; +package org.opentripplanner.ext.restapi.resources; import jakarta.ws.rs.GET; import jakarta.ws.rs.Path; @@ -10,11 +10,12 @@ import jakarta.ws.rs.core.UriInfo; import org.glassfish.grizzly.http.server.Request; import org.opentripplanner.api.common.Message; -import org.opentripplanner.api.common.RoutingResource; -import org.opentripplanner.api.mapping.PlannerErrorMapper; -import org.opentripplanner.api.mapping.TripPlanMapper; -import org.opentripplanner.api.mapping.TripSearchMetadataMapper; -import org.opentripplanner.api.model.error.PlannerError; +import org.opentripplanner.api.error.PlannerError; +import org.opentripplanner.apis.support.mapping.PlannerErrorMapper; +import org.opentripplanner.ext.restapi.mapping.TripPlanMapper; +import org.opentripplanner.ext.restapi.mapping.TripSearchMetadataMapper; +import org.opentripplanner.ext.restapi.model.ElevationMetadata; +import org.opentripplanner.ext.restapi.model.TripPlannerResponse; import org.opentripplanner.framework.application.OTPRequestTimeoutException; import org.opentripplanner.routing.api.request.RouteRequest; import org.opentripplanner.routing.api.response.RoutingResponse; diff --git a/src/main/java/org/opentripplanner/api/common/RequestToPreferencesMapper.java b/src/ext/java/org/opentripplanner/ext/restapi/resources/RequestToPreferencesMapper.java similarity index 90% rename from src/main/java/org/opentripplanner/api/common/RequestToPreferencesMapper.java rename to src/ext/java/org/opentripplanner/ext/restapi/resources/RequestToPreferencesMapper.java index aa827ae5b4c..fee01e63d66 100644 --- a/src/main/java/org/opentripplanner/api/common/RequestToPreferencesMapper.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/resources/RequestToPreferencesMapper.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.common; +package org.opentripplanner.ext.restapi.resources; import jakarta.validation.constraints.NotNull; import java.util.function.Consumer; @@ -9,6 +9,7 @@ import org.opentripplanner.routing.api.request.preference.Relax; import org.opentripplanner.routing.api.request.preference.RoutingPreferences; import org.opentripplanner.routing.api.request.preference.VehicleParkingPreferences; +import org.opentripplanner.routing.api.request.preference.VehicleRentalPreferences; import org.opentripplanner.routing.core.BicycleOptimizeType; class RequestToPreferencesMapper { @@ -36,7 +37,6 @@ void map() { mapTransfer(boardAndAlightSlack); - maptRental(); mapItineraryFilter(); mapSystem(); } @@ -49,6 +49,7 @@ private void mapCar() { setIfNotNull(req.carParkCost, parking::withParkCost); setIfNotNull(req.carParkTime, parking::withParkTime); }); + car.withRental(this::mapRental); }); } @@ -85,6 +86,7 @@ private void mapBike() { setIfNotNull(req.bikeParkCost, parking::withParkCost); setIfNotNull(req.bikeParkTime, parking::withParkTime); }); + bike.withRental(this::mapRental); }); } @@ -133,14 +135,19 @@ private void mapTransfer(BoardAndAlightSlack boardAndAlightSlack) { }); } - private void maptRental() { - preferences.withRental(rental -> { - setIfNotNull( - req.keepingRentedBicycleAtDestinationCost, - rental::withArrivingInRentalVehicleAtDestinationCost - ); - rental.withUseAvailabilityInformation(isPlannedForNow); - }); + private void mapRental(VehicleRentalPreferences.Builder rental) { + setIfNotNull( + req.allowKeepingRentedBicycleAtDestination, + rental::withAllowArrivingInRentedVehicleAtDestination + ); + setIfNotNull(req.allowedVehicleRentalNetworks, rental::withAllowedNetworks); + setIfNotNull(req.bannedVehicleRentalNetworks, rental::withBannedNetworks); + + setIfNotNull( + req.keepingRentedBicycleAtDestinationCost, + rental::withArrivingInRentalVehicleAtDestinationCost + ); + rental.withUseAvailabilityInformation(isPlannedForNow); } private void mapItineraryFilter() { diff --git a/src/main/java/org/opentripplanner/api/resource/Routers.java b/src/ext/java/org/opentripplanner/ext/restapi/resources/Routers.java similarity index 93% rename from src/main/java/org/opentripplanner/api/resource/Routers.java rename to src/ext/java/org/opentripplanner/ext/restapi/resources/Routers.java index 63ed28fbea3..9cfab49017c 100644 --- a/src/main/java/org/opentripplanner/api/resource/Routers.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/resources/Routers.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.resource; +package org.opentripplanner.ext.restapi.resources; import jakarta.annotation.security.PermitAll; import jakarta.ws.rs.GET; @@ -7,8 +7,8 @@ import jakarta.ws.rs.Produces; import jakarta.ws.rs.core.Context; import jakarta.ws.rs.core.MediaType; -import org.opentripplanner.api.model.ApiRouterInfo; -import org.opentripplanner.api.model.ApiRouterList; +import org.opentripplanner.ext.restapi.model.ApiRouterInfo; +import org.opentripplanner.ext.restapi.model.ApiRouterList; import org.opentripplanner.routing.error.GraphNotFoundException; import org.opentripplanner.standalone.api.OtpServerRequestContext; diff --git a/src/main/java/org/opentripplanner/api/common/RoutingResource.java b/src/ext/java/org/opentripplanner/ext/restapi/resources/RoutingResource.java similarity index 98% rename from src/main/java/org/opentripplanner/api/common/RoutingResource.java rename to src/ext/java/org/opentripplanner/ext/restapi/resources/RoutingResource.java index 9cb4f139bc4..c53e35c63ff 100644 --- a/src/main/java/org/opentripplanner/api/common/RoutingResource.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/resources/RoutingResource.java @@ -1,7 +1,7 @@ -package org.opentripplanner.api.common; +package org.opentripplanner.ext.restapi.resources; import static org.opentripplanner.api.common.LocationStringParser.fromOldStyleString; -import static org.opentripplanner.api.common.RequestToPreferencesMapper.setIfNotNull; +import static org.opentripplanner.ext.restapi.resources.RequestToPreferencesMapper.setIfNotNull; import jakarta.ws.rs.DefaultValue; import jakarta.ws.rs.QueryParam; @@ -745,16 +745,6 @@ protected RouteRequest buildRequest(MultivaluedMap queryParamete journey.setModes(modes.getRequestModes()); } - { - var rental = journey.rental(); - setIfNotNull( - allowKeepingRentedBicycleAtDestination, - rental::setAllowArrivingInRentedVehicleAtDestination - ); - setIfNotNull(allowedVehicleRentalNetworks, rental::setAllowedNetworks); - setIfNotNull(bannedVehicleRentalNetworks, rental::setBannedNetworks); - } - setIfNotNull(arriveBy, request::setArriveBy); { diff --git a/src/main/java/org/opentripplanner/index/ValidateParameters.java b/src/ext/java/org/opentripplanner/ext/restapi/resources/ValidateParameters.java similarity index 96% rename from src/main/java/org/opentripplanner/index/ValidateParameters.java rename to src/ext/java/org/opentripplanner/ext/restapi/resources/ValidateParameters.java index 41149ac31e3..5a94ca318f7 100644 --- a/src/main/java/org/opentripplanner/index/ValidateParameters.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/resources/ValidateParameters.java @@ -1,4 +1,4 @@ -package org.opentripplanner.index; +package org.opentripplanner.ext.restapi.resources; import jakarta.ws.rs.BadRequestException; import java.util.HashSet; diff --git a/src/main/java/org/opentripplanner/api/resource/package-info.java b/src/ext/java/org/opentripplanner/ext/restapi/resources/package-info.java similarity index 74% rename from src/main/java/org/opentripplanner/api/resource/package-info.java rename to src/ext/java/org/opentripplanner/ext/restapi/resources/package-info.java index 4d67f4b2100..7b66666ee5d 100644 --- a/src/main/java/org/opentripplanner/api/resource/package-info.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/resources/package-info.java @@ -2,4 +2,4 @@ * This package contains the JAX-RS-annotated REST resource classes for the OpenTripPlanner public * API, i.e. the Jersey REST endpoints. */ -package org.opentripplanner.api.resource; +package org.opentripplanner.ext.restapi.resources; diff --git a/src/main/java/org/opentripplanner/api/json/FeedScopedIdDeserializer.java b/src/ext/java/org/opentripplanner/ext/restapi/serialization/FeedScopedIdDeserializer.java similarity index 94% rename from src/main/java/org/opentripplanner/api/json/FeedScopedIdDeserializer.java rename to src/ext/java/org/opentripplanner/ext/restapi/serialization/FeedScopedIdDeserializer.java index aaccc900c1c..75b1b58bfee 100644 --- a/src/main/java/org/opentripplanner/api/json/FeedScopedIdDeserializer.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/serialization/FeedScopedIdDeserializer.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.json; +package org.opentripplanner.ext.restapi.serialization; import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.JsonProcessingException; diff --git a/src/main/java/org/opentripplanner/api/json/FeedScopedIdKeyDeserializer.java b/src/ext/java/org/opentripplanner/ext/restapi/serialization/FeedScopedIdKeyDeserializer.java similarity index 91% rename from src/main/java/org/opentripplanner/api/json/FeedScopedIdKeyDeserializer.java rename to src/ext/java/org/opentripplanner/ext/restapi/serialization/FeedScopedIdKeyDeserializer.java index a59f46e1052..75270e9dd0b 100644 --- a/src/main/java/org/opentripplanner/api/json/FeedScopedIdKeyDeserializer.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/serialization/FeedScopedIdKeyDeserializer.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.json; +package org.opentripplanner.ext.restapi.serialization; import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterxml.jackson.databind.KeyDeserializer; diff --git a/src/main/java/org/opentripplanner/api/json/FeedScopedIdSerializer.java b/src/ext/java/org/opentripplanner/ext/restapi/serialization/FeedScopedIdSerializer.java similarity index 96% rename from src/main/java/org/opentripplanner/api/json/FeedScopedIdSerializer.java rename to src/ext/java/org/opentripplanner/ext/restapi/serialization/FeedScopedIdSerializer.java index 1e357f642b1..c9c67e675c4 100644 --- a/src/main/java/org/opentripplanner/api/json/FeedScopedIdSerializer.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/serialization/FeedScopedIdSerializer.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.json; +package org.opentripplanner.ext.restapi.serialization; import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.core.JsonProcessingException; diff --git a/src/main/java/org/opentripplanner/api/json/JSONObjectMapperProvider.java b/src/ext/java/org/opentripplanner/ext/restapi/serialization/JSONObjectMapperProvider.java similarity index 98% rename from src/main/java/org/opentripplanner/api/json/JSONObjectMapperProvider.java rename to src/ext/java/org/opentripplanner/ext/restapi/serialization/JSONObjectMapperProvider.java index d4138563fc7..e271e945ca1 100644 --- a/src/main/java/org/opentripplanner/api/json/JSONObjectMapperProvider.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/serialization/JSONObjectMapperProvider.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.json; +package org.opentripplanner.ext.restapi.serialization; import com.bedatadriven.jackson.datatype.jts.JtsModule; import com.fasterxml.jackson.annotation.JsonInclude.Include; diff --git a/src/ext/java/org/opentripplanner/ext/siri/SiriAlertsUpdateHandler.java b/src/ext/java/org/opentripplanner/ext/siri/SiriAlertsUpdateHandler.java index bc19650d1cd..68b055bda46 100644 --- a/src/ext/java/org/opentripplanner/ext/siri/SiriAlertsUpdateHandler.java +++ b/src/ext/java/org/opentripplanner/ext/siri/SiriAlertsUpdateHandler.java @@ -141,6 +141,9 @@ private TransitAlert handleAlert(PtSituationElement situation) { if (situation.getVersionedAtTime() != null) { alert.withUpdatedTime(situation.getVersionedAtTime()); } + if (situation.getVersion() != null && situation.getVersion().getValue() != null) { + alert.withVersion(situation.getVersion().getValue().intValue()); + } ArrayList periods = new ArrayList<>(); if (situation.getValidityPeriods().size() > 0) { diff --git a/src/ext/java/org/opentripplanner/ext/vectortiles/VectorTilesResource.java b/src/ext/java/org/opentripplanner/ext/vectortiles/VectorTilesResource.java index f22145d261d..af2715d6928 100644 --- a/src/ext/java/org/opentripplanner/ext/vectortiles/VectorTilesResource.java +++ b/src/ext/java/org/opentripplanner/ext/vectortiles/VectorTilesResource.java @@ -17,7 +17,7 @@ import java.util.Objects; import java.util.function.Predicate; import org.glassfish.grizzly.http.server.Request; -import org.opentripplanner.api.model.TileJson; +import org.opentripplanner.apis.support.TileJson; import org.opentripplanner.ext.vectortiles.layers.stations.StationsLayerBuilder; import org.opentripplanner.ext.vectortiles.layers.stops.StopsLayerBuilder; import org.opentripplanner.ext.vectortiles.layers.vehicleparkings.VehicleParkingGroupsLayerBuilder; diff --git a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/stations/DigitransitStationPropertyMapper.java b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/stations/DigitransitStationPropertyMapper.java index b706a0ae8c3..a828cd37a7c 100644 --- a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/stations/DigitransitStationPropertyMapper.java +++ b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/stations/DigitransitStationPropertyMapper.java @@ -6,8 +6,8 @@ import java.util.Map; import java.util.stream.Collectors; import org.json.simple.JSONArray; -import org.opentripplanner.api.mapping.I18NStringMapper; -import org.opentripplanner.api.mapping.PropertyMapper; +import org.opentripplanner.apis.support.mapping.PropertyMapper; +import org.opentripplanner.framework.i18n.I18NStringMapper; import org.opentripplanner.inspector.vector.KeyValue; import org.opentripplanner.transit.model.framework.FeedScopedId; import org.opentripplanner.transit.model.site.Station; diff --git a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/stations/StationsLayerBuilder.java b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/stations/StationsLayerBuilder.java index 56e8be7b3e4..449a1489d89 100644 --- a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/stations/StationsLayerBuilder.java +++ b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/stations/StationsLayerBuilder.java @@ -9,7 +9,7 @@ import org.locationtech.jts.geom.Envelope; import org.locationtech.jts.geom.Geometry; import org.locationtech.jts.geom.Point; -import org.opentripplanner.api.mapping.PropertyMapper; +import org.opentripplanner.apis.support.mapping.PropertyMapper; import org.opentripplanner.ext.vectortiles.VectorTilesResource; import org.opentripplanner.framework.geometry.GeometryUtils; import org.opentripplanner.inspector.vector.LayerBuilder; diff --git a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/stops/DigitransitStopPropertyMapper.java b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/stops/DigitransitStopPropertyMapper.java index 502adc7899f..2c5a4519e96 100644 --- a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/stops/DigitransitStopPropertyMapper.java +++ b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/stops/DigitransitStopPropertyMapper.java @@ -8,8 +8,8 @@ import java.util.stream.Collectors; import org.json.simple.JSONArray; import org.json.simple.JSONObject; -import org.opentripplanner.api.mapping.I18NStringMapper; -import org.opentripplanner.api.mapping.PropertyMapper; +import org.opentripplanner.apis.support.mapping.PropertyMapper; +import org.opentripplanner.framework.i18n.I18NStringMapper; import org.opentripplanner.inspector.vector.KeyValue; import org.opentripplanner.transit.model.network.TripPattern; import org.opentripplanner.transit.model.site.RegularStop; diff --git a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/stops/StopsLayerBuilder.java b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/stops/StopsLayerBuilder.java index b6558f3cbe5..6d15816669e 100644 --- a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/stops/StopsLayerBuilder.java +++ b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/stops/StopsLayerBuilder.java @@ -7,7 +7,7 @@ import java.util.stream.Collectors; import org.locationtech.jts.geom.Envelope; import org.locationtech.jts.geom.Geometry; -import org.opentripplanner.api.mapping.PropertyMapper; +import org.opentripplanner.apis.support.mapping.PropertyMapper; import org.opentripplanner.ext.vectortiles.VectorTilesResource; import org.opentripplanner.inspector.vector.LayerBuilder; import org.opentripplanner.inspector.vector.LayerParameters; diff --git a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/DigitransitVehicleParkingGroupPropertyMapper.java b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/DigitransitVehicleParkingGroupPropertyMapper.java index a5bb4ae2c8b..33f415c157a 100644 --- a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/DigitransitVehicleParkingGroupPropertyMapper.java +++ b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/DigitransitVehicleParkingGroupPropertyMapper.java @@ -5,8 +5,8 @@ import java.util.Locale; import org.json.simple.JSONArray; import org.json.simple.JSONObject; -import org.opentripplanner.api.mapping.I18NStringMapper; -import org.opentripplanner.api.mapping.PropertyMapper; +import org.opentripplanner.apis.support.mapping.PropertyMapper; +import org.opentripplanner.framework.i18n.I18NStringMapper; import org.opentripplanner.inspector.vector.KeyValue; public class DigitransitVehicleParkingGroupPropertyMapper diff --git a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/DigitransitVehicleParkingPropertyMapper.java b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/DigitransitVehicleParkingPropertyMapper.java index 993675dcf06..892d4907395 100644 --- a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/DigitransitVehicleParkingPropertyMapper.java +++ b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/DigitransitVehicleParkingPropertyMapper.java @@ -5,8 +5,8 @@ import java.util.List; import java.util.Locale; import javax.annotation.Nonnull; -import org.opentripplanner.api.mapping.I18NStringMapper; -import org.opentripplanner.api.mapping.PropertyMapper; +import org.opentripplanner.apis.support.mapping.PropertyMapper; +import org.opentripplanner.framework.i18n.I18NStringMapper; import org.opentripplanner.inspector.vector.KeyValue; import org.opentripplanner.routing.vehicle_parking.VehicleParking; diff --git a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/StadtnaviVehicleParkingPropertyMapper.java b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/StadtnaviVehicleParkingPropertyMapper.java index 0e7c5cd90e8..c938f9736fd 100644 --- a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/StadtnaviVehicleParkingPropertyMapper.java +++ b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/StadtnaviVehicleParkingPropertyMapper.java @@ -4,8 +4,8 @@ import java.util.List; import java.util.Locale; import org.json.simple.JSONObject; -import org.opentripplanner.api.mapping.I18NStringMapper; -import org.opentripplanner.api.mapping.PropertyMapper; +import org.opentripplanner.apis.support.mapping.PropertyMapper; +import org.opentripplanner.framework.i18n.I18NStringMapper; import org.opentripplanner.inspector.vector.KeyValue; import org.opentripplanner.model.calendar.openinghours.OsmOpeningHoursSupport; import org.opentripplanner.routing.vehicle_parking.VehicleParking; diff --git a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/VehicleParkingGroupsLayerBuilder.java b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/VehicleParkingGroupsLayerBuilder.java index f39d042ad6e..0cd1d84868b 100644 --- a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/VehicleParkingGroupsLayerBuilder.java +++ b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/VehicleParkingGroupsLayerBuilder.java @@ -8,7 +8,7 @@ import org.locationtech.jts.geom.Envelope; import org.locationtech.jts.geom.Geometry; import org.locationtech.jts.geom.Point; -import org.opentripplanner.api.mapping.PropertyMapper; +import org.opentripplanner.apis.support.mapping.PropertyMapper; import org.opentripplanner.ext.vectortiles.VectorTilesResource; import org.opentripplanner.framework.geometry.GeometryUtils; import org.opentripplanner.inspector.vector.LayerBuilder; diff --git a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/VehicleParkingsLayerBuilder.java b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/VehicleParkingsLayerBuilder.java index 66dde2e4258..95326172415 100644 --- a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/VehicleParkingsLayerBuilder.java +++ b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/VehicleParkingsLayerBuilder.java @@ -11,7 +11,7 @@ import org.locationtech.jts.geom.Envelope; import org.locationtech.jts.geom.Geometry; import org.locationtech.jts.geom.Point; -import org.opentripplanner.api.mapping.PropertyMapper; +import org.opentripplanner.apis.support.mapping.PropertyMapper; import org.opentripplanner.ext.vectortiles.VectorTilesResource; import org.opentripplanner.framework.geometry.GeometryUtils; import org.opentripplanner.inspector.vector.LayerBuilder; diff --git a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/VehicleRentalLayerBuilder.java b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/VehicleRentalLayerBuilder.java index 4e181ed4fa1..0869aeb2ba8 100644 --- a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/VehicleRentalLayerBuilder.java +++ b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/VehicleRentalLayerBuilder.java @@ -7,7 +7,7 @@ import org.locationtech.jts.geom.Envelope; import org.locationtech.jts.geom.Geometry; import org.locationtech.jts.geom.Point; -import org.opentripplanner.api.mapping.PropertyMapper; +import org.opentripplanner.apis.support.mapping.PropertyMapper; import org.opentripplanner.ext.vectortiles.VectorTilesResource; import org.opentripplanner.framework.geometry.GeometryUtils; import org.opentripplanner.inspector.vector.LayerBuilder; diff --git a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/mapper/DigitransitRealtimeVehicleRentalStationPropertyMapper.java b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/mapper/DigitransitRealtimeVehicleRentalStationPropertyMapper.java index a6f2aa63fd4..4ceb7124d52 100644 --- a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/mapper/DigitransitRealtimeVehicleRentalStationPropertyMapper.java +++ b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/mapper/DigitransitRealtimeVehicleRentalStationPropertyMapper.java @@ -7,8 +7,8 @@ import java.util.Collection; import java.util.List; import java.util.Locale; -import org.opentripplanner.api.mapping.I18NStringMapper; -import org.opentripplanner.api.mapping.PropertyMapper; +import org.opentripplanner.apis.support.mapping.PropertyMapper; +import org.opentripplanner.framework.i18n.I18NStringMapper; import org.opentripplanner.inspector.vector.KeyValue; import org.opentripplanner.service.vehiclerental.model.VehicleRentalStation; diff --git a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/mapper/DigitransitRentalVehiclePropertyMapper.java b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/mapper/DigitransitRentalVehiclePropertyMapper.java index e1093467d4d..33e661866bc 100644 --- a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/mapper/DigitransitRentalVehiclePropertyMapper.java +++ b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/mapper/DigitransitRentalVehiclePropertyMapper.java @@ -4,7 +4,7 @@ import java.util.ArrayList; import java.util.Collection; -import org.opentripplanner.api.mapping.PropertyMapper; +import org.opentripplanner.apis.support.mapping.PropertyMapper; import org.opentripplanner.inspector.vector.KeyValue; import org.opentripplanner.service.vehiclerental.model.VehicleRentalVehicle; diff --git a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/mapper/DigitransitVehicleRentalPropertyMapper.java b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/mapper/DigitransitVehicleRentalPropertyMapper.java index 1839edf8905..3114b072934 100644 --- a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/mapper/DigitransitVehicleRentalPropertyMapper.java +++ b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/mapper/DigitransitVehicleRentalPropertyMapper.java @@ -3,8 +3,8 @@ import java.util.Collection; import java.util.List; import java.util.Locale; -import org.opentripplanner.api.mapping.I18NStringMapper; -import org.opentripplanner.api.mapping.PropertyMapper; +import org.opentripplanner.apis.support.mapping.PropertyMapper; +import org.opentripplanner.framework.i18n.I18NStringMapper; import org.opentripplanner.inspector.vector.KeyValue; import org.opentripplanner.service.vehiclerental.model.VehicleRentalPlace; diff --git a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/mapper/DigitransitVehicleRentalStationPropertyMapper.java b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/mapper/DigitransitVehicleRentalStationPropertyMapper.java index 962c1db4b04..67fb00efa85 100644 --- a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/mapper/DigitransitVehicleRentalStationPropertyMapper.java +++ b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/mapper/DigitransitVehicleRentalStationPropertyMapper.java @@ -5,8 +5,8 @@ import java.util.List; import java.util.Locale; import java.util.stream.Collectors; -import org.opentripplanner.api.mapping.I18NStringMapper; -import org.opentripplanner.api.mapping.PropertyMapper; +import org.opentripplanner.apis.support.mapping.PropertyMapper; +import org.opentripplanner.framework.i18n.I18NStringMapper; import org.opentripplanner.inspector.vector.KeyValue; import org.opentripplanner.service.vehiclerental.model.VehicleRentalPlace; import org.opentripplanner.service.vehiclerental.model.VehicleRentalStation; diff --git a/src/main/java/org/opentripplanner/api/model/error/PlannerError.java b/src/main/java/org/opentripplanner/api/error/PlannerError.java similarity index 94% rename from src/main/java/org/opentripplanner/api/model/error/PlannerError.java rename to src/main/java/org/opentripplanner/api/error/PlannerError.java index a41a3f6148a..1a35275a7cd 100644 --- a/src/main/java/org/opentripplanner/api/model/error/PlannerError.java +++ b/src/main/java/org/opentripplanner/api/error/PlannerError.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.model.error; +package org.opentripplanner.api.error; import java.util.List; import org.opentripplanner.api.common.Message; diff --git a/src/main/java/org/opentripplanner/api/package.md b/src/main/java/org/opentripplanner/api/package.md deleted file mode 100644 index 5498b2e4c47..00000000000 --- a/src/main/java/org/opentripplanner/api/package.md +++ /dev/null @@ -1,8 +0,0 @@ -# OTP REST API - -This package contains the code which exposes OpenTripPlanner services to the outside world as a REST -API. This includes Jersey REST resource classes (in the "resource" subpackage, picked up by Jersey's -package scanning process), and the classes modeling the structure of the response (in the "model" -subpackage). We provide OTP with the REST API as a embedded standalone Grizzly-based command-line -server. - diff --git a/src/main/java/org/opentripplanner/api/resource/GraphInspectorVectorTileResource.java b/src/main/java/org/opentripplanner/api/resource/GraphInspectorVectorTileResource.java index 2c21e0396ce..8c50b2e3bdc 100644 --- a/src/main/java/org/opentripplanner/api/resource/GraphInspectorVectorTileResource.java +++ b/src/main/java/org/opentripplanner/api/resource/GraphInspectorVectorTileResource.java @@ -17,7 +17,7 @@ import java.util.Objects; import java.util.function.Predicate; import org.glassfish.grizzly.http.server.Request; -import org.opentripplanner.api.model.TileJson; +import org.opentripplanner.apis.support.TileJson; import org.opentripplanner.inspector.vector.AreaStopsLayerBuilder; import org.opentripplanner.inspector.vector.LayerBuilder; import org.opentripplanner.inspector.vector.LayerParameters; diff --git a/src/main/java/org/opentripplanner/api/configuration/APIEndpoints.java b/src/main/java/org/opentripplanner/apis/APIEndpoints.java similarity index 88% rename from src/main/java/org/opentripplanner/api/configuration/APIEndpoints.java rename to src/main/java/org/opentripplanner/apis/APIEndpoints.java index b0d38aa00cd..fc49c02431f 100644 --- a/src/main/java/org/opentripplanner/api/configuration/APIEndpoints.java +++ b/src/main/java/org/opentripplanner/apis/APIEndpoints.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.configuration; +package org.opentripplanner.apis; import static org.opentripplanner.framework.application.OTPFeature.APIBikeRental; import static org.opentripplanner.framework.application.OTPFeature.APIGraphInspectorTile; @@ -6,6 +6,7 @@ import static org.opentripplanner.framework.application.OTPFeature.APIUpdaterStatus; import static org.opentripplanner.framework.application.OTPFeature.ActuatorAPI; import static org.opentripplanner.framework.application.OTPFeature.GtfsGraphQlApi; +import static org.opentripplanner.framework.application.OTPFeature.LegacyRestApi; import static org.opentripplanner.framework.application.OTPFeature.ReportApi; import static org.opentripplanner.framework.application.OTPFeature.SandboxAPIGeocoder; import static org.opentripplanner.framework.application.OTPFeature.SandboxAPIMapboxVectorTilesApi; @@ -17,11 +18,8 @@ import java.util.Collection; import java.util.Collections; import java.util.List; -import org.opentripplanner.api.resource.BikeRental; import org.opentripplanner.api.resource.GraphInspectorTileResource; import org.opentripplanner.api.resource.GraphInspectorVectorTileResource; -import org.opentripplanner.api.resource.PlannerResource; -import org.opentripplanner.api.resource.Routers; import org.opentripplanner.api.resource.ServerInfo; import org.opentripplanner.api.resource.UpdaterStatusResource; import org.opentripplanner.apis.gtfs.GtfsGraphQLAPI; @@ -30,10 +28,13 @@ import org.opentripplanner.ext.geocoder.GeocoderResource; import org.opentripplanner.ext.parkAndRideApi.ParkAndRideResource; import org.opentripplanner.ext.reportapi.resource.ReportResource; +import org.opentripplanner.ext.restapi.resources.BikeRental; +import org.opentripplanner.ext.restapi.resources.IndexAPI; +import org.opentripplanner.ext.restapi.resources.PlannerResource; +import org.opentripplanner.ext.restapi.resources.Routers; import org.opentripplanner.ext.traveltime.TravelTimeResource; import org.opentripplanner.ext.vectortiles.VectorTilesResource; import org.opentripplanner.framework.application.OTPFeature; -import org.opentripplanner.index.IndexAPI; /** * Configure API resource endpoints. @@ -43,14 +44,8 @@ public class APIEndpoints { private final List> resources = new ArrayList<>(); private APIEndpoints() { - // Add mandatory APIs - add(Routers.class); - add(PlannerResource.class); - add(IndexAPI.class); - // Add feature enabled APIs, these can be enabled by default, some is not. // See the OTPFeature enum for details. - addIfEnabled(APIBikeRental, BikeRental.class); addIfEnabled(APIGraphInspectorTile, GraphInspectorTileResource.class); addIfEnabled(APIGraphInspectorTile, GraphInspectorVectorTileResource.class); addIfEnabled(APIServerInfo, ServerInfo.class); @@ -65,6 +60,12 @@ private APIEndpoints() { addIfEnabled(SandboxAPIParkAndRideApi, ParkAndRideResource.class); addIfEnabled(SandboxAPIGeocoder, GeocoderResource.class); addIfEnabled(SandboxAPITravelTime, TravelTimeResource.class); + + // scheduled to be removed + addIfEnabled(APIBikeRental, BikeRental.class); + addIfEnabled(LegacyRestApi, Routers.class); + addIfEnabled(LegacyRestApi, PlannerResource.class); + addIfEnabled(LegacyRestApi, IndexAPI.class); } /** diff --git a/src/main/java/org/opentripplanner/apis/gtfs/GtfsGraphQLAPI.java b/src/main/java/org/opentripplanner/apis/gtfs/GtfsGraphQLAPI.java index 20d15b1cfe8..b9b93190816 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/GtfsGraphQLAPI.java +++ b/src/main/java/org/opentripplanner/apis/gtfs/GtfsGraphQLAPI.java @@ -21,7 +21,7 @@ import java.util.Map; import java.util.concurrent.Callable; import java.util.concurrent.Future; -import org.opentripplanner.api.json.GraphQLResponseSerializer; +import org.opentripplanner.framework.graphql.GraphQLResponseSerializer; import org.opentripplanner.standalone.api.OtpServerRequestContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/src/main/java/org/opentripplanner/apis/gtfs/GtfsGraphQLIndex.java b/src/main/java/org/opentripplanner/apis/gtfs/GtfsGraphQLIndex.java index c70836a581f..b50bbaa9b9e 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/GtfsGraphQLIndex.java +++ b/src/main/java/org/opentripplanner/apis/gtfs/GtfsGraphQLIndex.java @@ -26,7 +26,6 @@ import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; -import org.opentripplanner.api.json.GraphQLResponseSerializer; import org.opentripplanner.apis.gtfs.datafetchers.AgencyImpl; import org.opentripplanner.apis.gtfs.datafetchers.AlertEntityTypeResolver; import org.opentripplanner.apis.gtfs.datafetchers.AlertImpl; @@ -88,6 +87,7 @@ import org.opentripplanner.ext.actuator.MicrometerGraphQLInstrumentation; import org.opentripplanner.framework.application.OTPFeature; import org.opentripplanner.framework.concurrent.OtpRequestThreadFactory; +import org.opentripplanner.framework.graphql.GraphQLResponseSerializer; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/LegImpl.java b/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/LegImpl.java index b13f6123d4d..639cb95bf28 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/LegImpl.java +++ b/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/LegImpl.java @@ -6,11 +6,11 @@ import java.util.Objects; import java.util.stream.Collectors; import org.locationtech.jts.geom.Geometry; -import org.opentripplanner.api.mapping.LocalDateMapper; import org.opentripplanner.apis.gtfs.GraphQLRequestContext; import org.opentripplanner.apis.gtfs.generated.GraphQLDataFetchers; import org.opentripplanner.apis.gtfs.generated.GraphQLTypes; import org.opentripplanner.apis.gtfs.mapping.NumberMapper; +import org.opentripplanner.ext.restapi.mapping.LocalDateMapper; import org.opentripplanner.ext.ridehailing.model.RideEstimate; import org.opentripplanner.ext.ridehailing.model.RideHailingLeg; import org.opentripplanner.framework.graphql.GraphQLUtils; diff --git a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/PatternImpl.java b/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/PatternImpl.java index 241434c664f..88db00c3c4e 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/PatternImpl.java +++ b/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/PatternImpl.java @@ -13,10 +13,10 @@ import org.locationtech.jts.geom.Coordinate; import org.locationtech.jts.geom.Geometry; import org.locationtech.jts.geom.LineString; -import org.opentripplanner.api.support.SemanticHash; import org.opentripplanner.apis.gtfs.GraphQLRequestContext; import org.opentripplanner.apis.gtfs.generated.GraphQLDataFetchers; import org.opentripplanner.apis.gtfs.generated.GraphQLTypes; +import org.opentripplanner.apis.support.SemanticHash; import org.opentripplanner.framework.graphql.GraphQLUtils; import org.opentripplanner.framework.time.ServiceDateUtils; import org.opentripplanner.routing.alertpatch.EntitySelector; diff --git a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/PlanImpl.java b/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/PlanImpl.java index 9ae58be1334..b9bdfde9cbc 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/PlanImpl.java +++ b/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/PlanImpl.java @@ -3,9 +3,9 @@ import graphql.schema.DataFetcher; import graphql.schema.DataFetchingEnvironment; import java.util.stream.Collectors; -import org.opentripplanner.api.mapping.PlannerErrorMapper; import org.opentripplanner.api.resource.DebugOutput; import org.opentripplanner.apis.gtfs.generated.GraphQLDataFetchers; +import org.opentripplanner.apis.support.mapping.PlannerErrorMapper; import org.opentripplanner.model.plan.Itinerary; import org.opentripplanner.model.plan.StopArrival; import org.opentripplanner.model.plan.paging.cursor.PageCursor; diff --git a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/RoutingErrorImpl.java b/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/RoutingErrorImpl.java index 7c516930888..5c4bd7099c6 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/RoutingErrorImpl.java +++ b/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/RoutingErrorImpl.java @@ -4,9 +4,9 @@ import graphql.schema.DataFetcher; import graphql.schema.DataFetchingEnvironment; -import org.opentripplanner.api.mapping.PlannerErrorMapper; import org.opentripplanner.apis.gtfs.generated.GraphQLDataFetchers; import org.opentripplanner.apis.gtfs.generated.GraphQLTypes; +import org.opentripplanner.apis.support.mapping.PlannerErrorMapper; import org.opentripplanner.routing.api.response.RoutingError; public class RoutingErrorImpl implements GraphQLDataFetchers.GraphQLRoutingError { diff --git a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/TripImpl.java b/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/TripImpl.java index 2502d2b9539..21bff637976 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/TripImpl.java +++ b/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/TripImpl.java @@ -15,7 +15,6 @@ import java.util.stream.Collectors; import org.locationtech.jts.geom.Geometry; import org.locationtech.jts.geom.LineString; -import org.opentripplanner.api.support.SemanticHash; import org.opentripplanner.apis.gtfs.GraphQLRequestContext; import org.opentripplanner.apis.gtfs.GraphQLUtils; import org.opentripplanner.apis.gtfs.generated.GraphQLDataFetchers; @@ -23,6 +22,7 @@ import org.opentripplanner.apis.gtfs.generated.GraphQLTypes.GraphQLBikesAllowed; import org.opentripplanner.apis.gtfs.mapping.BikesAllowedMapper; import org.opentripplanner.apis.gtfs.model.TripOccupancy; +import org.opentripplanner.apis.support.SemanticHash; import org.opentripplanner.framework.time.ServiceDateUtils; import org.opentripplanner.model.Timetable; import org.opentripplanner.model.TripTimeOnDate; diff --git a/src/main/java/org/opentripplanner/apis/gtfs/mapping/RouteRequestMapper.java b/src/main/java/org/opentripplanner/apis/gtfs/mapping/RouteRequestMapper.java index ab9e8bce823..790064aba22 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/mapping/RouteRequestMapper.java +++ b/src/main/java/org/opentripplanner/apis/gtfs/mapping/RouteRequestMapper.java @@ -22,6 +22,7 @@ import org.opentripplanner.routing.api.request.framework.CostLinearFunction; import org.opentripplanner.routing.api.request.preference.ItineraryFilterDebugProfile; import org.opentripplanner.routing.api.request.preference.VehicleParkingPreferences; +import org.opentripplanner.routing.api.request.preference.VehicleRentalPreferences; import org.opentripplanner.routing.api.request.request.filter.SelectRequest; import org.opentripplanner.routing.api.request.request.filter.TransitFilterRequest; import org.opentripplanner.routing.core.BicycleOptimizeType; @@ -84,11 +85,13 @@ public static RouteRequest toRouteRequest( } bike.withParking(parking -> setParkingPreferences(callWith, parking)); + bike.withRental(rental -> setRentalPreferences(callWith, request, rental)); }); preferences.withCar(car -> { callWith.argument("carReluctance", car::withReluctance); car.withParking(parking -> setParkingPreferences(callWith, parking)); + car.withRental(rental -> setRentalPreferences(callWith, request, rental)); }); preferences.withWalk(b -> { @@ -97,13 +100,6 @@ public static RouteRequest toRouteRequest( callWith.argument("walkBoardCost", b::withBoardCost); callWith.argument("walkSafetyFactor", b::withSafetyFactor); }); - preferences.withRental(rental -> { - callWith.argument( - "keepingRentedBicycleAtDestinationCost", - rental::withArrivingInRentalVehicleAtDestinationCost - ); - rental.withUseAvailabilityInformation(request.isTripPlannedForNow()); - }); // TODO Add support for all debug filter variants callWith.argument( "debugItineraryFilter", @@ -148,10 +144,6 @@ public static RouteRequest toRouteRequest( }); }); - callWith.argument( - "allowKeepingRentedBicycleAtDestination", - request.journey().rental()::setAllowArrivingInRentedVehicleAtDestination - ); callWith.argument("arriveBy", request::setArriveBy); callWith.argument( @@ -231,22 +223,6 @@ public static RouteRequest toRouteRequest( // ((List)environment.getArgument("allowedTicketTypes")).forEach(ticketType -> request.allowedFares.add(ticketType.replaceFirst("_", ":"))); } - var vehicleRental = request.journey().rental(); - - // Deprecated, the next one will override this, if both are set - callWith.argument( - "allowedBikeRentalNetworks", - (Collection v) -> vehicleRental.setAllowedNetworks(new HashSet<>(v)) - ); - callWith.argument( - "allowedVehicleRentalNetworks", - (Collection v) -> vehicleRental.setAllowedNetworks(new HashSet<>(v)) - ); - callWith.argument( - "bannedVehicleRentalNetworks", - (Collection v) -> vehicleRental.setBannedNetworks(new HashSet<>(v)) - ); - callWith.argument( "locale", (String v) -> request.setLocale(GraphQLUtils.getLocale(environment, v)) @@ -324,6 +300,36 @@ private static void setParkingPreferences( ); } + private static void setRentalPreferences( + CallerWithEnvironment callWith, + RouteRequest request, + VehicleRentalPreferences.Builder rental + ) { + callWith.argument( + "keepingRentedBicycleAtDestinationCost", + rental::withArrivingInRentalVehicleAtDestinationCost + ); + rental.withUseAvailabilityInformation(request.isTripPlannedForNow()); + callWith.argument( + "allowKeepingRentedBicycleAtDestination", + rental::withAllowArrivingInRentedVehicleAtDestination + ); + + // Deprecated, the next one will override this, if both are set + callWith.argument( + "allowedBikeRentalNetworks", + (Collection v) -> rental.withAllowedNetworks(new HashSet<>(v)) + ); + callWith.argument( + "allowedVehicleRentalNetworks", + (Collection v) -> rental.withAllowedNetworks(new HashSet<>(v)) + ); + callWith.argument( + "bannedVehicleRentalNetworks", + (Collection v) -> rental.withBannedNetworks(new HashSet<>(v)) + ); + } + private static class CallerWithEnvironment { private final DataFetchingEnvironment environment; diff --git a/src/main/java/org/opentripplanner/apis/gtfs/mapping/StreetNoteMapper.java b/src/main/java/org/opentripplanner/apis/gtfs/mapping/StreetNoteMapper.java index baa601c7448..563200dbba0 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/mapping/StreetNoteMapper.java +++ b/src/main/java/org/opentripplanner/apis/gtfs/mapping/StreetNoteMapper.java @@ -1,6 +1,5 @@ package org.opentripplanner.apis.gtfs.mapping; -import org.opentripplanner.api.mapping.StreetNoteMaperMapper; import org.opentripplanner.framework.i18n.NonLocalizedString; import org.opentripplanner.routing.alertpatch.TimePeriod; import org.opentripplanner.routing.alertpatch.TransitAlert; @@ -11,7 +10,7 @@ public class StreetNoteMapper { /** - * Similar to {@link StreetNoteMaperMapper ::mapToApi}. + * Similar to {@link org.opentripplanner.apis.support.mapping.StreetNoteMapper ::mapToApi}. */ public static TransitAlert mapStreetNoteToAlert(StreetNote note) { // TODO: The ID is used only in the mapping, we should instead have two mappers for the fields diff --git a/src/main/java/org/opentripplanner/api/support/SemanticHash.java b/src/main/java/org/opentripplanner/apis/support/SemanticHash.java similarity index 99% rename from src/main/java/org/opentripplanner/api/support/SemanticHash.java rename to src/main/java/org/opentripplanner/apis/support/SemanticHash.java index bf7e8da8b01..2d1f35977fa 100644 --- a/src/main/java/org/opentripplanner/api/support/SemanticHash.java +++ b/src/main/java/org/opentripplanner/apis/support/SemanticHash.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.support; +package org.opentripplanner.apis.support; import com.google.common.hash.HashCode; import com.google.common.hash.HashFunction; diff --git a/src/main/java/org/opentripplanner/api/model/TileJson.java b/src/main/java/org/opentripplanner/apis/support/TileJson.java similarity index 97% rename from src/main/java/org/opentripplanner/api/model/TileJson.java rename to src/main/java/org/opentripplanner/apis/support/TileJson.java index d012241d892..2259d72d828 100644 --- a/src/main/java/org/opentripplanner/api/model/TileJson.java +++ b/src/main/java/org/opentripplanner/apis/support/TileJson.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.model; +package org.opentripplanner.apis.support; import jakarta.ws.rs.core.HttpHeaders; import jakarta.ws.rs.core.UriInfo; diff --git a/src/main/java/org/opentripplanner/api/mapping/PlannerErrorMapper.java b/src/main/java/org/opentripplanner/apis/support/mapping/PlannerErrorMapper.java similarity index 94% rename from src/main/java/org/opentripplanner/api/mapping/PlannerErrorMapper.java rename to src/main/java/org/opentripplanner/apis/support/mapping/PlannerErrorMapper.java index 204495110c1..9ec662f51e0 100644 --- a/src/main/java/org/opentripplanner/api/mapping/PlannerErrorMapper.java +++ b/src/main/java/org/opentripplanner/apis/support/mapping/PlannerErrorMapper.java @@ -1,8 +1,8 @@ -package org.opentripplanner.api.mapping; +package org.opentripplanner.apis.support.mapping; import java.util.List; import org.opentripplanner.api.common.Message; -import org.opentripplanner.api.model.error.PlannerError; +import org.opentripplanner.api.error.PlannerError; import org.opentripplanner.routing.api.response.InputField; import org.opentripplanner.routing.api.response.RoutingError; diff --git a/src/main/java/org/opentripplanner/api/mapping/PropertyMapper.java b/src/main/java/org/opentripplanner/apis/support/mapping/PropertyMapper.java similarity index 96% rename from src/main/java/org/opentripplanner/api/mapping/PropertyMapper.java rename to src/main/java/org/opentripplanner/apis/support/mapping/PropertyMapper.java index 88f102a2b06..dfb7def85c7 100644 --- a/src/main/java/org/opentripplanner/api/mapping/PropertyMapper.java +++ b/src/main/java/org/opentripplanner/apis/support/mapping/PropertyMapper.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.mapping; +package org.opentripplanner.apis.support.mapping; import edu.colorado.cires.cmg.mvt.VectorTile; import edu.colorado.cires.cmg.mvt.adapt.jts.IUserDataConverter; diff --git a/src/main/java/org/opentripplanner/api/mapping/StreetNoteMaperMapper.java b/src/main/java/org/opentripplanner/apis/support/mapping/StreetNoteMapper.java similarity index 85% rename from src/main/java/org/opentripplanner/api/mapping/StreetNoteMaperMapper.java rename to src/main/java/org/opentripplanner/apis/support/mapping/StreetNoteMapper.java index 9ee44d102bb..9cde403c2ed 100644 --- a/src/main/java/org/opentripplanner/api/mapping/StreetNoteMaperMapper.java +++ b/src/main/java/org/opentripplanner/apis/support/mapping/StreetNoteMapper.java @@ -1,17 +1,17 @@ -package org.opentripplanner.api.mapping; +package org.opentripplanner.apis.support.mapping; import java.util.List; import java.util.Locale; import java.util.Set; import java.util.stream.Collectors; -import org.opentripplanner.api.model.ApiAlert; +import org.opentripplanner.ext.restapi.model.ApiAlert; import org.opentripplanner.street.model.note.StreetNote; -public class StreetNoteMaperMapper { +public class StreetNoteMapper { private final Locale locale; - public StreetNoteMaperMapper(Locale locale) { + public StreetNoteMapper(Locale locale) { this.locale = locale; } diff --git a/src/main/java/org/opentripplanner/apis/transmodel/mapping/PreferencesMapper.java b/src/main/java/org/opentripplanner/apis/transmodel/mapping/PreferencesMapper.java index 2f8ea15515e..846437952e4 100644 --- a/src/main/java/org/opentripplanner/apis/transmodel/mapping/PreferencesMapper.java +++ b/src/main/java/org/opentripplanner/apis/transmodel/mapping/PreferencesMapper.java @@ -3,7 +3,6 @@ import static org.opentripplanner.apis.transmodel.mapping.preferences.BikePreferencesMapper.mapBikePreferences; import static org.opentripplanner.apis.transmodel.mapping.preferences.CarPreferencesMapper.mapCarPreferences; import static org.opentripplanner.apis.transmodel.mapping.preferences.ItineraryFilterPreferencesMapper.mapItineraryFilterPreferences; -import static org.opentripplanner.apis.transmodel.mapping.preferences.ItineraryFilterPreferencesMapper.mapRentalPreferences; import static org.opentripplanner.apis.transmodel.mapping.preferences.StreetPreferencesMapper.mapStreetPreferences; import static org.opentripplanner.apis.transmodel.mapping.preferences.TransferPreferencesMapper.mapTransferPreferences; import static org.opentripplanner.apis.transmodel.mapping.preferences.TransitPreferencesMapper.mapTransitPreferences; @@ -30,6 +29,5 @@ static void mapPreferences( preferences.withItineraryFilter(itineraryFilter -> mapItineraryFilterPreferences(itineraryFilter, environment, callWith) ); - preferences.withRental(rental -> mapRentalPreferences(rental, environment, callWith)); } } diff --git a/src/main/java/org/opentripplanner/apis/transmodel/mapping/TripRequestMapper.java b/src/main/java/org/opentripplanner/apis/transmodel/mapping/TripRequestMapper.java index f27798c295a..5c579501254 100644 --- a/src/main/java/org/opentripplanner/apis/transmodel/mapping/TripRequestMapper.java +++ b/src/main/java/org/opentripplanner/apis/transmodel/mapping/TripRequestMapper.java @@ -10,7 +10,6 @@ import java.util.List; import java.util.Locale; import java.util.Map; -import java.util.Set; import org.opentripplanner.apis.transmodel.TransmodelRequestContext; import org.opentripplanner.apis.transmodel.support.DataFetcherDecorator; import org.opentripplanner.apis.transmodel.support.GqlUtil; @@ -85,16 +84,6 @@ public static RouteRequest createRequest(DataFetchingEnvironment environment) { request.journey().transit().setUnpreferredRoutes(mapIDsToDomainNullSafe(lines)) ); - callWith.argument( - "whiteListed.rentalNetworks", - (List networks) -> request.journey().rental().setAllowedNetworks(Set.copyOf(networks)) - ); - - callWith.argument( - "banned.rentalNetworks", - (List networks) -> request.journey().rental().setBannedNetworks(Set.copyOf(networks)) - ); - if (GqlUtil.hasArgument(environment, "modes")) { request .journey() diff --git a/src/main/java/org/opentripplanner/apis/transmodel/mapping/preferences/BikePreferencesMapper.java b/src/main/java/org/opentripplanner/apis/transmodel/mapping/preferences/BikePreferencesMapper.java index d56dc09c251..3ccdd9007a4 100644 --- a/src/main/java/org/opentripplanner/apis/transmodel/mapping/preferences/BikePreferencesMapper.java +++ b/src/main/java/org/opentripplanner/apis/transmodel/mapping/preferences/BikePreferencesMapper.java @@ -1,5 +1,7 @@ package org.opentripplanner.apis.transmodel.mapping.preferences; +import static org.opentripplanner.apis.transmodel.mapping.preferences.RentalPreferencesMapper.mapRentalPreferences; + import org.opentripplanner.apis.transmodel.support.DataFetcherDecorator; import org.opentripplanner.routing.api.request.preference.BikePreferences; import org.opentripplanner.routing.core.BicycleOptimizeType; @@ -42,5 +44,7 @@ public static void mapBikePreferences( callWith.argument("triangleFactors.safety", triangle::withSafety); }); } + + bike.withRental(rental -> mapRentalPreferences(rental, callWith)); } } diff --git a/src/main/java/org/opentripplanner/apis/transmodel/mapping/preferences/CarPreferencesMapper.java b/src/main/java/org/opentripplanner/apis/transmodel/mapping/preferences/CarPreferencesMapper.java index d6ba995f53c..3a10fd6ea04 100644 --- a/src/main/java/org/opentripplanner/apis/transmodel/mapping/preferences/CarPreferencesMapper.java +++ b/src/main/java/org/opentripplanner/apis/transmodel/mapping/preferences/CarPreferencesMapper.java @@ -1,5 +1,7 @@ package org.opentripplanner.apis.transmodel.mapping.preferences; +import static org.opentripplanner.apis.transmodel.mapping.preferences.RentalPreferencesMapper.mapRentalPreferences; + import org.opentripplanner.apis.transmodel.support.DataFetcherDecorator; import org.opentripplanner.routing.api.request.preference.CarPreferences; @@ -8,6 +10,7 @@ public class CarPreferencesMapper { public static void mapCarPreferences(CarPreferences.Builder car, DataFetcherDecorator callWith) { // Walk reluctance is used for backward compatibility callWith.argument("walkReluctance", car::withReluctance); + car.withRental(rental -> mapRentalPreferences(rental, callWith)); // UNSUPPORTED PARAMETERS // Override WALK reluctance with CAR reluctance diff --git a/src/main/java/org/opentripplanner/apis/transmodel/mapping/preferences/ItineraryFilterPreferencesMapper.java b/src/main/java/org/opentripplanner/apis/transmodel/mapping/preferences/ItineraryFilterPreferencesMapper.java index 1f0b7ac3925..aa875606704 100644 --- a/src/main/java/org/opentripplanner/apis/transmodel/mapping/preferences/ItineraryFilterPreferencesMapper.java +++ b/src/main/java/org/opentripplanner/apis/transmodel/mapping/preferences/ItineraryFilterPreferencesMapper.java @@ -5,7 +5,6 @@ import org.opentripplanner.apis.transmodel.support.DataFetcherDecorator; import org.opentripplanner.routing.api.request.preference.ItineraryFilterDebugProfile; import org.opentripplanner.routing.api.request.preference.ItineraryFilterPreferences; -import org.opentripplanner.routing.api.request.preference.VehicleRentalPreferences; public class ItineraryFilterPreferencesMapper { @@ -20,15 +19,4 @@ public static void mapItineraryFilterPreferences( ); ItineraryFiltersInputType.mapToRequest(environment, callWith, itineraryFilter); } - - public static void mapRentalPreferences( - VehicleRentalPreferences.Builder rental, - DataFetchingEnvironment environment, - DataFetcherDecorator callWith - ) { - callWith.argument( - "useBikeRentalAvailabilityInformation", - rental::withUseAvailabilityInformation - ); - } } diff --git a/src/main/java/org/opentripplanner/apis/transmodel/mapping/preferences/RentalPreferencesMapper.java b/src/main/java/org/opentripplanner/apis/transmodel/mapping/preferences/RentalPreferencesMapper.java new file mode 100644 index 00000000000..b9ced6f0d6c --- /dev/null +++ b/src/main/java/org/opentripplanner/apis/transmodel/mapping/preferences/RentalPreferencesMapper.java @@ -0,0 +1,28 @@ +package org.opentripplanner.apis.transmodel.mapping.preferences; + +import java.util.List; +import java.util.Set; +import org.opentripplanner.apis.transmodel.support.DataFetcherDecorator; +import org.opentripplanner.routing.api.request.preference.VehicleRentalPreferences; + +public class RentalPreferencesMapper { + + public static void mapRentalPreferences( + VehicleRentalPreferences.Builder rental, + DataFetcherDecorator callWith + ) { + callWith.argument( + "whiteListed.rentalNetworks", + (List networks) -> rental.withAllowedNetworks(Set.copyOf(networks)) + ); + + callWith.argument( + "banned.rentalNetworks", + (List networks) -> rental.withBannedNetworks(Set.copyOf(networks)) + ); + callWith.argument( + "useBikeRentalAvailabilityInformation", + rental::withUseAvailabilityInformation + ); + } +} diff --git a/src/main/java/org/opentripplanner/apis/transmodel/model/DefaultRouteRequestType.java b/src/main/java/org/opentripplanner/apis/transmodel/model/DefaultRouteRequestType.java index 41f77669859..5e4dca2bfc2 100644 --- a/src/main/java/org/opentripplanner/apis/transmodel/model/DefaultRouteRequestType.java +++ b/src/main/java/org/opentripplanner/apis/transmodel/model/DefaultRouteRequestType.java @@ -184,7 +184,7 @@ private GraphQLObjectType createGraphQLType() { .name("bikeRentalPickupTime") .description("Time to rent a bike.") .type(Scalars.GraphQLInt) - .dataFetcher(env -> preferences.rental().pickupTime()) + .dataFetcher(env -> preferences.bike().rental().pickupTime()) .build() ) .field( @@ -193,7 +193,7 @@ private GraphQLObjectType createGraphQLType() { .name("bikeRentalPickupCost") .description("Cost to rent a bike.") .type(Scalars.GraphQLInt) - .dataFetcher(env -> preferences.rental().pickupCost()) + .dataFetcher(env -> preferences.bike().rental().pickupCost()) .build() ) .field( @@ -202,7 +202,7 @@ private GraphQLObjectType createGraphQLType() { .name("bikeRentalDropOffTime") .description("Time to drop-off a rented bike.") .type(Scalars.GraphQLInt) - .dataFetcher(env -> preferences.rental().dropoffTime()) + .dataFetcher(env -> preferences.bike().rental().dropoffTime()) .build() ) .field( @@ -211,7 +211,7 @@ private GraphQLObjectType createGraphQLType() { .name("bikeRentalDropOffCost") .description("Cost to drop-off a rented bike.") .type(Scalars.GraphQLInt) - .dataFetcher(env -> preferences.rental().dropoffCost()) + .dataFetcher(env -> preferences.bike().rental().dropoffCost()) .build() ) .field( diff --git a/src/main/java/org/opentripplanner/apis/transmodel/model/EnumTypes.java b/src/main/java/org/opentripplanner/apis/transmodel/model/EnumTypes.java index 70173062f8f..12aa19fbaea 100644 --- a/src/main/java/org/opentripplanner/apis/transmodel/model/EnumTypes.java +++ b/src/main/java/org/opentripplanner/apis/transmodel/model/EnumTypes.java @@ -291,7 +291,7 @@ public class EnumTypes { .value( "noTransitConnectionInSearchWindow", RoutingErrorCode.NO_TRANSIT_CONNECTION_IN_SEARCH_WINDOW, - "Transit connection was found, but it was outside the search window, see metadata for the next search window" + "A transit connection was found, but it was outside the search window. Use paging to navigate to a result." ) .value( "outsideBounds", diff --git a/src/main/java/org/opentripplanner/apis/transmodel/model/plan/RoutingErrorType.java b/src/main/java/org/opentripplanner/apis/transmodel/model/plan/RoutingErrorType.java index 79052f17b69..215e1983ca0 100644 --- a/src/main/java/org/opentripplanner/apis/transmodel/model/plan/RoutingErrorType.java +++ b/src/main/java/org/opentripplanner/apis/transmodel/model/plan/RoutingErrorType.java @@ -7,7 +7,7 @@ import graphql.schema.GraphQLFieldDefinition; import graphql.schema.GraphQLNonNull; import graphql.schema.GraphQLObjectType; -import org.opentripplanner.api.mapping.PlannerErrorMapper; +import org.opentripplanner.apis.support.mapping.PlannerErrorMapper; public class RoutingErrorType { diff --git a/src/main/java/org/opentripplanner/apis/transmodel/model/plan/TripPatternType.java b/src/main/java/org/opentripplanner/apis/transmodel/model/plan/TripPatternType.java index 31e33ae6e4d..158d6a9a042 100644 --- a/src/main/java/org/opentripplanner/apis/transmodel/model/plan/TripPatternType.java +++ b/src/main/java/org/opentripplanner/apis/transmodel/model/plan/TripPatternType.java @@ -193,6 +193,18 @@ public static GraphQLObjectType create( .dataFetcher(env -> itinerary(env).getGeneralizedCost()) .build() ) + .field( + GraphQLFieldDefinition + .newFieldDefinition() + .name("generalizedCost2") + .description( + "A second cost or weight of the itinerary. Some use-cases like pass-through " + + "and transit-priority-groups use a second cost during routing. This is used for debugging." + ) + .type(Scalars.GraphQLInt) + .dataFetcher(env -> itinerary(env).getGeneralizedCost2().orElse(null)) + .build() + ) .field( GraphQLFieldDefinition .newFieldDefinition() diff --git a/src/main/java/org/opentripplanner/apis/transmodel/model/plan/TripQuery.java b/src/main/java/org/opentripplanner/apis/transmodel/model/plan/TripQuery.java index d06c5954444..243ebdc1692 100644 --- a/src/main/java/org/opentripplanner/apis/transmodel/model/plan/TripQuery.java +++ b/src/main/java/org/opentripplanner/apis/transmodel/model/plan/TripQuery.java @@ -386,7 +386,7 @@ public static GraphQLFieldDefinition create( "rental trips." ) .type(Scalars.GraphQLBoolean) - .defaultValue(preferences.rental().useAvailabilityInformation()) + .defaultValue(preferences.bike().rental().useAvailabilityInformation()) .build() ) .argument( diff --git a/src/main/java/org/opentripplanner/apis/transmodel/model/plan/TripType.java b/src/main/java/org/opentripplanner/apis/transmodel/model/plan/TripType.java index d9c3c0caa02..053b261c08e 100644 --- a/src/main/java/org/opentripplanner/apis/transmodel/model/plan/TripType.java +++ b/src/main/java/org/opentripplanner/apis/transmodel/model/plan/TripType.java @@ -8,7 +8,7 @@ import graphql.schema.GraphQLNonNull; import graphql.schema.GraphQLObjectType; import java.util.stream.Collectors; -import org.opentripplanner.api.mapping.PlannerErrorMapper; +import org.opentripplanner.apis.support.mapping.PlannerErrorMapper; import org.opentripplanner.apis.transmodel.model.PlanResponse; import org.opentripplanner.apis.transmodel.support.GqlUtil; import org.opentripplanner.framework.graphql.GraphQLUtils; diff --git a/src/main/java/org/opentripplanner/apis/transmodel/model/siri/sx/PtSituationElementType.java b/src/main/java/org/opentripplanner/apis/transmodel/model/siri/sx/PtSituationElementType.java index b5616c2d3fc..0dc0e74d3b3 100644 --- a/src/main/java/org/opentripplanner/apis/transmodel/model/siri/sx/PtSituationElementType.java +++ b/src/main/java/org/opentripplanner/apis/transmodel/model/siri/sx/PtSituationElementType.java @@ -324,6 +324,15 @@ public static GraphQLObjectType create( }) .build() ) + .field( + GraphQLFieldDefinition + .newFieldDefinition() + .name("version") + .type(Scalars.GraphQLInt) + .description("Operator's version number for the situation element.") + .dataFetcher(environment -> environment.getSource().version()) + .build() + ) .field( GraphQLFieldDefinition .newFieldDefinition() diff --git a/src/main/java/org/opentripplanner/apis/transmodel/support/ExecutionResultMapper.java b/src/main/java/org/opentripplanner/apis/transmodel/support/ExecutionResultMapper.java index ecb5a38ef01..d0ccb198e16 100644 --- a/src/main/java/org/opentripplanner/apis/transmodel/support/ExecutionResultMapper.java +++ b/src/main/java/org/opentripplanner/apis/transmodel/support/ExecutionResultMapper.java @@ -4,8 +4,8 @@ import graphql.ExecutionResult; import graphql.GraphQLError; import jakarta.ws.rs.core.Response; -import org.opentripplanner.api.json.GraphQLResponseSerializer; import org.opentripplanner.framework.application.OTPRequestTimeoutException; +import org.opentripplanner.framework.graphql.GraphQLResponseSerializer; import org.opentripplanner.framework.http.OtpHttpStatus; /** diff --git a/src/main/java/org/opentripplanner/astar/model/BinHeap.java b/src/main/java/org/opentripplanner/astar/model/BinHeap.java index 9bc2b0762a8..1e9b540a77a 100644 --- a/src/main/java/org/opentripplanner/astar/model/BinHeap.java +++ b/src/main/java/org/opentripplanner/astar/model/BinHeap.java @@ -79,14 +79,6 @@ public void rekey(T e, double p) { prio[i] = p; } - public void dump() { - for (int i = 0; i <= capacity; i++) { - String topMarker = (i > size) ? "(UNUSED)" : ""; - System.out.printf("%d\t%f\t%s\t%s\n", i, prio[i], elem[i], topMarker); - } - System.out.printf("-----------------------\n"); - } - public void reset() { // empties the queue in one operation size = 0; @@ -135,8 +127,4 @@ public void resize(int capacity) { prio = Arrays.copyOf(prio, capacity + 1); elem = Arrays.copyOf(elem, capacity + 1); } - - public int getCapacity() { - return capacity; - } } diff --git a/src/main/java/org/opentripplanner/astar/model/ShortestPathTree.java b/src/main/java/org/opentripplanner/astar/model/ShortestPathTree.java index e373f9c785e..a6d7123cdfe 100644 --- a/src/main/java/org/opentripplanner/astar/model/ShortestPathTree.java +++ b/src/main/java/org/opentripplanner/astar/model/ShortestPathTree.java @@ -244,10 +244,6 @@ public void setAborted() { aborted = true; } - public boolean isAborted() { - return aborted; - } - public String toString() { return "ShortestPathTree(" + this.stateSets.size() + " vertices)"; } diff --git a/src/main/java/org/opentripplanner/astar/strategy/MaxCountSkipEdgeStrategy.java b/src/main/java/org/opentripplanner/astar/strategy/MaxCountSkipEdgeStrategy.java index bcae9dcdb86..0369e3e29db 100644 --- a/src/main/java/org/opentripplanner/astar/strategy/MaxCountSkipEdgeStrategy.java +++ b/src/main/java/org/opentripplanner/astar/strategy/MaxCountSkipEdgeStrategy.java @@ -1,12 +1,12 @@ package org.opentripplanner.astar.strategy; -import java.util.function.Function; +import java.util.function.Predicate; import org.opentripplanner.astar.spi.AStarEdge; import org.opentripplanner.astar.spi.AStarState; import org.opentripplanner.astar.spi.SkipEdgeStrategy; /** - * Skips edges when the specified number of desired vertices have been visited + * Skips edges when the specified number of desired vertices have been visited. */ public class MaxCountSkipEdgeStrategy< State extends AStarState, Edge extends AStarEdge @@ -14,11 +14,11 @@ public class MaxCountSkipEdgeStrategy< implements SkipEdgeStrategy { private final int maxCount; - private final Function shouldIncreaseCount; + private final Predicate shouldIncreaseCount; private int visited; - public MaxCountSkipEdgeStrategy(int count, Function shouldIncreaseCount) { + public MaxCountSkipEdgeStrategy(int count, Predicate shouldIncreaseCount) { this.maxCount = count; this.shouldIncreaseCount = shouldIncreaseCount; this.visited = 0; @@ -26,7 +26,7 @@ public MaxCountSkipEdgeStrategy(int count, Function shouldIncrea @Override public boolean shouldSkipEdge(State current, Edge edge) { - if (this.shouldIncreaseCount.apply(current)) { + if (shouldIncreaseCount.test(current)) { visited++; } return visited > maxCount; diff --git a/src/main/java/org/opentripplanner/framework/application/OTPFeature.java b/src/main/java/org/opentripplanner/framework/application/OTPFeature.java index 05d1284a883..816279d5a95 100644 --- a/src/main/java/org/opentripplanner/framework/application/OTPFeature.java +++ b/src/main/java/org/opentripplanner/framework/application/OTPFeature.java @@ -82,6 +82,7 @@ public enum OTPFeature { FaresV2(false, true, "Enable import of GTFS-Fares v2 data."), FlexRouting(false, true, "Enable FLEX routing."), GoogleCloudStorage(false, true, "Enable Google Cloud Storage integration."), + LegacyRestApi(true, true, "Enable legacy REST API. This API will be removed in the future."), RealtimeResolver( false, true, diff --git a/src/main/java/org/opentripplanner/framework/error/DefaultOtpError.java b/src/main/java/org/opentripplanner/framework/error/DefaultOtpError.java new file mode 100644 index 00000000000..32113ed1816 --- /dev/null +++ b/src/main/java/org/opentripplanner/framework/error/DefaultOtpError.java @@ -0,0 +1,29 @@ +package org.opentripplanner.framework.error; + +class DefaultOtpError implements OtpError { + + private final String errorCode; + private final String messageTemplate; + private final Object[] messageArguments; + + public DefaultOtpError(String errorCode, String messageTemplate, Object... messageArguments) { + this.errorCode = errorCode; + this.messageTemplate = messageTemplate; + this.messageArguments = messageArguments; + } + + @Override + public String errorCode() { + return errorCode; + } + + @Override + public String messageTemplate() { + return messageTemplate; + } + + @Override + public Object[] messageArguments() { + return messageArguments; + } +} diff --git a/src/main/java/org/opentripplanner/framework/error/OtpError.java b/src/main/java/org/opentripplanner/framework/error/OtpError.java index 6b2ff37945e..d04c12c3e33 100644 --- a/src/main/java/org/opentripplanner/framework/error/OtpError.java +++ b/src/main/java/org/opentripplanner/framework/error/OtpError.java @@ -34,4 +34,11 @@ public interface OtpError { default String message() { return String.format(Locale.ROOT, messageTemplate(), messageArguments()); } + + /** + * Factory method to create an OTPError. + */ + static OtpError of(String errorCode, String messageTemplate, Object... messageArguments) { + return new DefaultOtpError(errorCode, messageTemplate, messageArguments); + } } diff --git a/src/main/java/org/opentripplanner/api/json/GraphQLResponseSerializer.java b/src/main/java/org/opentripplanner/framework/graphql/GraphQLResponseSerializer.java similarity index 94% rename from src/main/java/org/opentripplanner/api/json/GraphQLResponseSerializer.java rename to src/main/java/org/opentripplanner/framework/graphql/GraphQLResponseSerializer.java index caba621294c..cb3b146a113 100644 --- a/src/main/java/org/opentripplanner/api/json/GraphQLResponseSerializer.java +++ b/src/main/java/org/opentripplanner/framework/graphql/GraphQLResponseSerializer.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.json; +package org.opentripplanner.framework.graphql; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; @@ -10,6 +10,7 @@ import java.util.Map; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; +import org.opentripplanner.ext.restapi.serialization.JSONObjectMapperProvider; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/src/main/java/org/opentripplanner/api/mapping/I18NStringMapper.java b/src/main/java/org/opentripplanner/framework/i18n/I18NStringMapper.java similarity index 77% rename from src/main/java/org/opentripplanner/api/mapping/I18NStringMapper.java rename to src/main/java/org/opentripplanner/framework/i18n/I18NStringMapper.java index 6b40a07b953..acdb30b301f 100644 --- a/src/main/java/org/opentripplanner/api/mapping/I18NStringMapper.java +++ b/src/main/java/org/opentripplanner/framework/i18n/I18NStringMapper.java @@ -1,9 +1,8 @@ -package org.opentripplanner.api.mapping; +package org.opentripplanner.framework.i18n; import java.util.Locale; import javax.annotation.Nonnull; import javax.annotation.Nullable; -import org.opentripplanner.framework.i18n.I18NString; public class I18NStringMapper { @@ -24,7 +23,7 @@ public String mapNonnullToApi(I18NString string) { } @Nullable - static String mapToApi(I18NString string, Locale locale) { + public static String mapToApi(I18NString string, Locale locale) { return string == null ? null : string.toString(locale); } } diff --git a/src/main/java/org/opentripplanner/graph_builder/module/NearbyStopFinder.java b/src/main/java/org/opentripplanner/graph_builder/module/NearbyStopFinder.java index ba776ac5243..360cdaee363 100644 --- a/src/main/java/org/opentripplanner/graph_builder/module/NearbyStopFinder.java +++ b/src/main/java/org/opentripplanner/graph_builder/module/NearbyStopFinder.java @@ -47,14 +47,8 @@ import org.opentripplanner.transit.service.TransitService; /** - * These library functions are used by the streetless and streetful stop linkers, and in profile - * transfer generation. - * TODO OTP2 Fold these into org.opentripplanner.routing.graphfinder.StreetGraphFinder - * These are not library functions, this is instantiated as an object. Define lifecycle of the object (reuse?). - * Because AStar instances should only be used once, NearbyStopFinder should only be used once. - * Ideally they could also be used in long distance mode and profile routing for the street segments. - * For each stop, it finds the closest stops on all other patterns. This reduces the number of transfer edges - * significantly compared to simple radius-constrained all-to-all stop linkage. + * This class contains code for finding nearby stops from a given vertex. It is being used by access + * and egress searches as well as transfer generation. */ public class NearbyStopFinder { @@ -100,6 +94,8 @@ public NearbyStopFinder( * that the result will include the origin vertex if it is an instance of StopVertex. This is * intentional: we don't want to return the next stop down the line for trip patterns that pass * through the origin vertex. + * Taking the patterns into account reduces the number of transfers significantly compared to + * simple traverse-duration-constrained all-to-all stop linkage. */ public Set findNearbyStopsConsideringPatterns( Vertex vertex, @@ -227,15 +223,12 @@ public List findNearbyStopsViaStreets( for (State state : spt.getAllStates()) { Vertex targetVertex = state.getVertex(); if (originVertices.contains(targetVertex)) continue; - if (targetVertex instanceof TransitStopVertex && state.isFinal()) { - stopsFound.add( - NearbyStop.nearbyStopForState(state, ((TransitStopVertex) targetVertex).getStop()) - ); + if (targetVertex instanceof TransitStopVertex tsv && state.isFinal()) { + stopsFound.add(NearbyStop.nearbyStopForState(state, tsv.getStop())); } if ( OTPFeature.FlexRouting.isOn() && - targetVertex instanceof StreetVertex && - !((StreetVertex) targetVertex).areaStops().isEmpty() + targetVertex instanceof StreetVertex streetVertex && !streetVertex.areaStops().isEmpty() ) { for (AreaStop areaStop : ((StreetVertex) targetVertex).areaStops()) { // This is for a simplification, so that we only return one vertex from each @@ -314,7 +307,7 @@ private SkipEdgeStrategy getSkipEdgeStrategy( if (maxStopCount > 0) { var strategy = new MaxCountSkipEdgeStrategy<>( maxStopCount, - NearbyStopFinder::isTransitVertex + NearbyStopFinder::hasReachedStop ); return new ComposingSkipEdgeStrategy<>(strategy, durationSkipEdgeStrategy); } @@ -360,15 +353,23 @@ private boolean canBoardFlex(State state, boolean reverse) { return edges .stream() - .anyMatch(e -> - e instanceof StreetEdge && ((StreetEdge) e).getPermission().allows(TraverseMode.CAR) - ); + .anyMatch(e -> e instanceof StreetEdge se && se.getPermission().allows(TraverseMode.CAR)); } /** - * Checks if the {@code state} as at a transit vertex. + * Checks if the {@code state} is at a transit vertex and if it's final, which means that the state + * can actually board a vehicle. + *

+ * This is important because there can be cases where states that cannot actually board the vehicle + * can dominate those that can thereby leading to zero found stops when this predicate is used with + * the {@link MaxCountSkipEdgeStrategy}. + *

+ * An example of this would be an egress/reverse search with a very high walk reluctance where + * the states that speculatively rent a vehicle move the walk states down the A* priority queue + * until the required number of stops are reached to abort the search, leading to zero egress + * results. */ - public static boolean isTransitVertex(State state) { - return state.getVertex() instanceof TransitStopVertex; + public static boolean hasReachedStop(State state) { + return state.getVertex() instanceof TransitStopVertex && state.isFinal(); } } diff --git a/src/main/java/org/opentripplanner/graph_builder/module/islandpruning/PruneIslands.java b/src/main/java/org/opentripplanner/graph_builder/module/islandpruning/PruneIslands.java index d3024a144f5..00404845349 100644 --- a/src/main/java/org/opentripplanner/graph_builder/module/islandpruning/PruneIslands.java +++ b/src/main/java/org/opentripplanner/graph_builder/module/islandpruning/PruneIslands.java @@ -25,10 +25,7 @@ import org.opentripplanner.street.model.edge.AreaEdge; import org.opentripplanner.street.model.edge.AreaEdgeList; import org.opentripplanner.street.model.edge.Edge; -import org.opentripplanner.street.model.edge.ElevatorEdge; -import org.opentripplanner.street.model.edge.FreeEdge; import org.opentripplanner.street.model.edge.StreetEdge; -import org.opentripplanner.street.model.edge.StreetTransitEntityLink; import org.opentripplanner.street.model.vertex.StreetVertex; import org.opentripplanner.street.model.vertex.TransitStopVertex; import org.opentripplanner.street.model.vertex.Vertex; @@ -338,16 +335,6 @@ private void collectNeighbourVertices( } State s0 = new State(gv, request); for (Edge e : gv.getOutgoing()) { - if ( - !( - e instanceof StreetEdge || - e instanceof ElevatorEdge || - e instanceof FreeEdge || - e instanceof StreetTransitEntityLink - ) - ) { - continue; - } if ( e instanceof StreetEdge && shouldMatchNoThruType != ((StreetEdge) e).isNoThruTraffic(traverseMode) diff --git a/src/main/java/org/opentripplanner/inspector/vector/AreaStopsLayerBuilder.java b/src/main/java/org/opentripplanner/inspector/vector/AreaStopsLayerBuilder.java index 1604cf7d8d1..5e4539e1f5c 100644 --- a/src/main/java/org/opentripplanner/inspector/vector/AreaStopsLayerBuilder.java +++ b/src/main/java/org/opentripplanner/inspector/vector/AreaStopsLayerBuilder.java @@ -7,7 +7,7 @@ import java.util.function.Function; import org.locationtech.jts.geom.Envelope; import org.locationtech.jts.geom.Geometry; -import org.opentripplanner.api.mapping.PropertyMapper; +import org.opentripplanner.apis.support.mapping.PropertyMapper; import org.opentripplanner.transit.model.site.AreaStop; import org.opentripplanner.transit.service.TransitService; diff --git a/src/main/java/org/opentripplanner/inspector/vector/DebugClientAreaStopPropertyMapper.java b/src/main/java/org/opentripplanner/inspector/vector/DebugClientAreaStopPropertyMapper.java index 88f7a17385b..63c58dd9b05 100644 --- a/src/main/java/org/opentripplanner/inspector/vector/DebugClientAreaStopPropertyMapper.java +++ b/src/main/java/org/opentripplanner/inspector/vector/DebugClientAreaStopPropertyMapper.java @@ -3,8 +3,8 @@ import java.util.Collection; import java.util.List; import java.util.Locale; -import org.opentripplanner.api.mapping.I18NStringMapper; -import org.opentripplanner.api.mapping.PropertyMapper; +import org.opentripplanner.apis.support.mapping.PropertyMapper; +import org.opentripplanner.framework.i18n.I18NStringMapper; import org.opentripplanner.transit.model.site.AreaStop; import org.opentripplanner.transit.service.TransitService; diff --git a/src/main/java/org/opentripplanner/inspector/vector/LayerBuilder.java b/src/main/java/org/opentripplanner/inspector/vector/LayerBuilder.java index 3e796487271..949bbef0a94 100644 --- a/src/main/java/org/opentripplanner/inspector/vector/LayerBuilder.java +++ b/src/main/java/org/opentripplanner/inspector/vector/LayerBuilder.java @@ -10,7 +10,7 @@ import org.locationtech.jts.geom.Envelope; import org.locationtech.jts.geom.Geometry; import org.locationtech.jts.geom.GeometryFactory; -import org.opentripplanner.api.mapping.PropertyMapper; +import org.opentripplanner.apis.support.mapping.PropertyMapper; import org.opentripplanner.framework.geometry.GeometryUtils; /** diff --git a/src/main/java/org/opentripplanner/inspector/vector/LayerParameters.java b/src/main/java/org/opentripplanner/inspector/vector/LayerParameters.java index 2718c649797..ca4a6a64c76 100644 --- a/src/main/java/org/opentripplanner/inspector/vector/LayerParameters.java +++ b/src/main/java/org/opentripplanner/inspector/vector/LayerParameters.java @@ -1,6 +1,6 @@ package org.opentripplanner.inspector.vector; -import org.opentripplanner.api.mapping.PropertyMapper; +import org.opentripplanner.apis.support.mapping.PropertyMapper; /** * Configuration options for a single vector tile layer. diff --git a/src/main/java/org/opentripplanner/inspector/vector/geofencing/GeofencingZonesLayerBuilder.java b/src/main/java/org/opentripplanner/inspector/vector/geofencing/GeofencingZonesLayerBuilder.java index 8a77b8502ea..1764451cc89 100644 --- a/src/main/java/org/opentripplanner/inspector/vector/geofencing/GeofencingZonesLayerBuilder.java +++ b/src/main/java/org/opentripplanner/inspector/vector/geofencing/GeofencingZonesLayerBuilder.java @@ -4,7 +4,7 @@ import java.util.Map; import org.locationtech.jts.geom.Envelope; import org.locationtech.jts.geom.Geometry; -import org.opentripplanner.api.mapping.PropertyMapper; +import org.opentripplanner.apis.support.mapping.PropertyMapper; import org.opentripplanner.framework.geometry.GeometryUtils; import org.opentripplanner.inspector.vector.LayerBuilder; import org.opentripplanner.inspector.vector.LayerParameters; diff --git a/src/main/java/org/opentripplanner/inspector/vector/geofencing/GeofencingZonesPropertyMapper.java b/src/main/java/org/opentripplanner/inspector/vector/geofencing/GeofencingZonesPropertyMapper.java index 0d0f7b44fe9..98c9cf23eca 100644 --- a/src/main/java/org/opentripplanner/inspector/vector/geofencing/GeofencingZonesPropertyMapper.java +++ b/src/main/java/org/opentripplanner/inspector/vector/geofencing/GeofencingZonesPropertyMapper.java @@ -6,7 +6,7 @@ import java.util.Collection; import java.util.List; -import org.opentripplanner.api.mapping.PropertyMapper; +import org.opentripplanner.apis.support.mapping.PropertyMapper; import org.opentripplanner.inspector.vector.KeyValue; import org.opentripplanner.street.model.vertex.Vertex; diff --git a/src/main/java/org/opentripplanner/model/plan/Itinerary.java b/src/main/java/org/opentripplanner/model/plan/Itinerary.java index 58320bf1652..d1252c45f2d 100644 --- a/src/main/java/org/opentripplanner/model/plan/Itinerary.java +++ b/src/main/java/org/opentripplanner/model/plan/Itinerary.java @@ -17,6 +17,7 @@ import org.opentripplanner.framework.tostring.ToStringBuilder; import org.opentripplanner.model.SystemNotice; import org.opentripplanner.model.fare.ItineraryFares; +import org.opentripplanner.raptor.api.model.RaptorConstants; import org.opentripplanner.raptor.api.path.PathStringBuilder; import org.opentripplanner.routing.algorithm.raptoradapter.transit.cost.RaptorCostConverter; import org.opentripplanner.routing.api.request.RouteRequest; @@ -43,6 +44,7 @@ public class Itinerary implements ItinerarySortKey { private Double elevationLost = 0.0; private Double elevationGained = 0.0; private int generalizedCost = UNKNOWN; + private Integer generalizedCost2 = null; private TimeAndCost accessPenalty = null; private TimeAndCost egressPenalty = null; private int waitTimeOptimizedCost = UNKNOWN; @@ -260,6 +262,7 @@ public String toString() { .addDuration("transitTime", transitDuration) .addDuration("waitingTime", waitingDuration) .addNum("generalizedCost", generalizedCost, UNKNOWN) + .addNum("generalizedCost2", generalizedCost2) .addNum("waitTimeOptimizedCost", waitTimeOptimizedCost, UNKNOWN) .addNum("transferPriorityCost", transferPriorityCost, UNKNOWN) .addNum("nonTransitDistance", nonTransitDistanceMeters, "m") @@ -306,7 +309,12 @@ public String toStr() { buf.stop(leg.getTo().name.toString()); } - buf.summary(RaptorCostConverter.toRaptorCost(generalizedCost)); + // The generalizedCost2 is printed as is, it is a special cost and the scale depends on the + // use-case. + buf.summary( + RaptorCostConverter.toRaptorCost(generalizedCost), + getGeneralizedCost2().orElse(RaptorConstants.NOT_SET) + ); return buf.toString(); } @@ -495,6 +503,24 @@ public void setGeneralizedCost(int generalizedCost) { this.generalizedCost = generalizedCost; } + /** + * The transit router allows the usage of a second generalized-cost parameter to be used in + * routing. In Raptor this is called c2, but in OTP it is generalized-cost-2. What this cost + * represents depends on the use-case and the unit and scale is also given by the use-case. + *

+ * Currently, the pass-through search and the transit-priority uses this. This is relevant for + * anyone who wants to debug a search and tune the system. + *

+ * {@link RaptorConstants#NOT_SET} indicate that the cost is not set/computed. + */ + public Optional getGeneralizedCost2() { + return Optional.ofNullable(generalizedCost2); + } + + public void setGeneralizedCost2(Integer generalizedCost2) { + this.generalizedCost2 = generalizedCost2; + } + @Nullable public TimeAndCost getAccessPenalty() { return accessPenalty; diff --git a/src/main/java/org/opentripplanner/netex/mapping/NetexMapper.java b/src/main/java/org/opentripplanner/netex/mapping/NetexMapper.java index 26016947c09..8fc30ae166a 100644 --- a/src/main/java/org/opentripplanner/netex/mapping/NetexMapper.java +++ b/src/main/java/org/opentripplanner/netex/mapping/NetexMapper.java @@ -11,6 +11,7 @@ import java.util.Objects; import java.util.Optional; import java.util.Set; +import java.util.stream.Collectors; import org.opentripplanner.graph_builder.issue.api.DataImportIssueStore; import org.opentripplanner.model.StopTime; import org.opentripplanner.model.calendar.ServiceCalendar; @@ -460,19 +461,36 @@ private void mapTripPatterns(Map serviceIds) { for (JourneyPattern_VersionStructure journeyPattern : currentNetexIndex .getJourneyPatternsById() .localValues()) { - TripPatternMapperResult result = tripPatternMapper.mapTripPattern(journeyPattern); + tripPatternMapper + .mapTripPattern(journeyPattern) + .ifPresent(this::applyTripPatternMapperResult); + } + } - for (Map.Entry> it : result.tripStopTimes.entrySet()) { - transitBuilder.getStopTimesSortedByTrip().put(it.getKey(), it.getValue()); - transitBuilder.getTripsById().add(it.getKey()); - } - for (var it : result.tripPatterns.entries()) { - transitBuilder.getTripPatterns().put(it.getKey(), it.getValue()); - } - currentMapperIndexes.addStopTimesByNetexId(result.stopTimeByNetexId); - groupMapper.scheduledStopPointsIndex.putAll(Multimaps.asMap(result.scheduledStopPointsIndex)); - transitBuilder.getTripOnServiceDates().addAll(result.tripOnServiceDates); + private void applyTripPatternMapperResult(TripPatternMapperResult result) { + var stopPattern = result.tripPattern().getStopPattern(); + var journeyPatternExists = transitBuilder + .getTripPatterns() + .get(stopPattern) + .stream() + .anyMatch(tripPattern -> result.tripPattern().getId().equals(tripPattern.getId())); + if (journeyPatternExists) { + issueStore.add( + "DuplicateJourneyPattern", + "Duplicate of JourneyPattern %s found", + result.tripPattern().getId().getId() + ); + } + + for (Map.Entry> it : result.tripStopTimes().entrySet()) { + transitBuilder.getStopTimesSortedByTrip().put(it.getKey(), it.getValue()); + transitBuilder.getTripsById().add(it.getKey()); } + + transitBuilder.getTripPatterns().put(stopPattern, result.tripPattern()); + currentMapperIndexes.addStopTimesByNetexId(result.stopTimeByNetexId()); + groupMapper.scheduledStopPointsIndex.putAll(Multimaps.asMap(result.scheduledStopPointsIndex())); + transitBuilder.getTripOnServiceDates().addAll(result.tripOnServiceDates()); } private void mapNoticeAssignments() { diff --git a/src/main/java/org/opentripplanner/netex/mapping/TripPatternMapper.java b/src/main/java/org/opentripplanner/netex/mapping/TripPatternMapper.java index 6fa000c1049..f0d06b8871d 100644 --- a/src/main/java/org/opentripplanner/netex/mapping/TripPatternMapper.java +++ b/src/main/java/org/opentripplanner/netex/mapping/TripPatternMapper.java @@ -5,10 +5,12 @@ import jakarta.xml.bind.JAXBElement; import java.util.ArrayList; import java.util.Collection; +import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Objects; +import java.util.Optional; import java.util.stream.Collectors; import org.opentripplanner.graph_builder.issue.api.DataImportIssueStore; import org.opentripplanner.model.StopTime; @@ -84,8 +86,6 @@ class TripPatternMapper { private final Deduplicator deduplicator; - private TripPatternMapperResult result; - TripPatternMapper( DataImportIssueStore issueStore, FeedScopedIdFactory idFactory, @@ -157,9 +157,7 @@ class TripPatternMapper { } } - TripPatternMapperResult mapTripPattern(JourneyPattern_VersionStructure journeyPattern) { - // Make sure the result is clean, by creating a new object. - result = new TripPatternMapperResult(); + Optional mapTripPattern(JourneyPattern_VersionStructure journeyPattern) { Collection serviceJourneys = serviceJourniesByPatternId.get( journeyPattern.getId() ); @@ -170,10 +168,14 @@ TripPatternMapperResult mapTripPattern(JourneyPattern_VersionStructure journeyPa "ServiceJourneyPattern %s does not contain any serviceJourneys.", journeyPattern.getId() ); - return result; + return Optional.empty(); } List trips = new ArrayList<>(); + ArrayListMultimap scheduledStopPointsIndex = ArrayListMultimap.create(); + HashMap> tripStopTimes = new HashMap<>(); + Map stopTimeByNetexId = new HashMap<>(); + ArrayList tripOnServiceDates = new ArrayList<>(); for (ServiceJourney serviceJourney : serviceJourneys) { Trip trip = mapTrip(journeyPattern, serviceJourney); @@ -184,7 +186,7 @@ TripPatternMapperResult mapTripPattern(JourneyPattern_VersionStructure journeyPa } // Add the dated service journey to the model for this trip [if it exists] - mapDatedServiceJourney(journeyPattern, serviceJourney, trip); + tripOnServiceDates.addAll(mapDatedServiceJourney(journeyPattern, serviceJourney, trip)); StopTimesMapperResult stopTimes = stopTimesMapper.mapToStopTimes( journeyPattern, @@ -198,25 +200,22 @@ TripPatternMapperResult mapTripPattern(JourneyPattern_VersionStructure journeyPa continue; } - result.scheduledStopPointsIndex.putAll( - serviceJourney.getId(), - stopTimes.scheduledStopPointIds - ); - result.tripStopTimes.put(trip, stopTimes.stopTimes); - result.stopTimeByNetexId.putAll(stopTimes.stopTimeByNetexId); + scheduledStopPointsIndex.putAll(serviceJourney.getId(), stopTimes.scheduledStopPointIds); + tripStopTimes.put(trip, stopTimes.stopTimes); + stopTimeByNetexId.putAll(stopTimes.stopTimeByNetexId); trips.add(trip); } // No trips successfully mapped if (trips.isEmpty()) { - return result; + return Optional.empty(); } // Create StopPattern from any trip (since they are part of the same JourneyPattern) StopPattern stopPattern = deduplicator.deduplicateObject( StopPattern.class, - new StopPattern(result.tripStopTimes.get(trips.get(0))) + new StopPattern(tripStopTimes.get(trips.get(0))) ); var tripPatternModes = new HashSet(); @@ -246,7 +245,7 @@ TripPatternMapperResult mapTripPattern(JourneyPattern_VersionStructure journeyPa ); } - TripPatternBuilder tripPatternBuilder = TripPattern + var tripPattern = TripPattern .of(idFactory.createId(journeyPattern.getId())) .withRoute(lookupRoute(journeyPattern)) .withStopPattern(stopPattern) @@ -256,30 +255,35 @@ TripPatternMapperResult mapTripPattern(JourneyPattern_VersionStructure journeyPa .withName(journeyPattern.getName() == null ? "" : journeyPattern.getName().getValue()) .withHopGeometries( serviceLinkMapper.getGeometriesByJourneyPattern(journeyPattern, stopPattern) - ); - - TripPattern tripPattern = tripPatternBuilder.build(); - createTripTimes(trips, tripPattern); - - result.tripPatterns.put(stopPattern, tripPattern); - - return result; + ) + .build(); + createTripTimes(trips, tripStopTimes).forEach(tripPattern::add); + + return Optional.of( + new TripPatternMapperResult( + tripPattern, + scheduledStopPointsIndex, + tripStopTimes, + stopTimeByNetexId, + tripOnServiceDates + ) + ); } - private void mapDatedServiceJourney( + private ArrayList mapDatedServiceJourney( JourneyPattern_VersionStructure journeyPattern, ServiceJourney serviceJourney, Trip trip ) { + var tripsOnServiceDates = new ArrayList(); if (datedServiceJourneysBySJId.containsKey(serviceJourney.getId())) { for (DatedServiceJourney datedServiceJourney : datedServiceJourneysBySJId.get( serviceJourney.getId() )) { - result.tripOnServiceDates.add( - mapDatedServiceJourney(journeyPattern, trip, datedServiceJourney) - ); + tripsOnServiceDates.add(mapDatedServiceJourney(journeyPattern, trip, datedServiceJourney)); } } + return tripsOnServiceDates; } private TripOnServiceDate mapDatedServiceJourney( @@ -360,9 +364,13 @@ private org.opentripplanner.transit.model.network.Route lookupRoute( return otpRouteById.get(idFactory.createId(lineId)); } - private void createTripTimes(List trips, TripPattern tripPattern) { + private List createTripTimes( + List trips, + Map> tripStopTimes + ) { + var tripTimesResult = new ArrayList(); for (Trip trip : trips) { - List stopTimes = result.tripStopTimes.get(trip); + List stopTimes = tripStopTimes.get(trip); if (stopTimes.isEmpty()) { issueStore.add( "TripWithoutTripTimes", @@ -372,12 +380,13 @@ private void createTripTimes(List trips, TripPattern tripPattern) { } else { try { TripTimes tripTimes = TripTimesFactory.tripTimes(trip, stopTimes, deduplicator); - tripPattern.add(tripTimes); + tripTimesResult.add(tripTimes); } catch (DataValidationException e) { issueStore.add(e.error()); } } } + return tripTimesResult; } private Trip mapTrip( diff --git a/src/main/java/org/opentripplanner/netex/mapping/TripPatternMapperResult.java b/src/main/java/org/opentripplanner/netex/mapping/TripPatternMapperResult.java index 6b14fea5d31..f2f75cd2561 100644 --- a/src/main/java/org/opentripplanner/netex/mapping/TripPatternMapperResult.java +++ b/src/main/java/org/opentripplanner/netex/mapping/TripPatternMapperResult.java @@ -13,24 +13,15 @@ import org.opentripplanner.transit.model.timetable.TripOnServiceDate; /** - * This mapper returnes two collections, so we need to use a simple wraper to be able to return the - * result from the mapping method. + * Wrapper class for the result of TripPatternMapper + * + * @param scheduledStopPointsIndex A map from trip/serviceJourney id to an ordered list of scheduled stop point ids. + * @param stopTimeByNetexId stopTimes by the timetabled-passing-time id */ -class TripPatternMapperResult { - - /** - * A map from trip/serviceJourney id to an ordered list of scheduled stop point ids. - */ - final ArrayListMultimap scheduledStopPointsIndex = ArrayListMultimap.create(); - - final Map> tripStopTimes = new HashMap<>(); - - final Multimap tripPatterns = ArrayListMultimap.create(); - - /** - * stopTimes by the timetabled-passing-time id - */ - final Map stopTimeByNetexId = new HashMap<>(); - - final ArrayList tripOnServiceDates = new ArrayList<>(); -} +record TripPatternMapperResult( + TripPattern tripPattern, + ArrayListMultimap scheduledStopPointsIndex, + Map> tripStopTimes, + Map stopTimeByNetexId, + ArrayList tripOnServiceDates +) {} diff --git a/src/main/java/org/opentripplanner/raptor/RaptorService.java b/src/main/java/org/opentripplanner/raptor/RaptorService.java index 450f993de1c..d8e7fcd3dcd 100644 --- a/src/main/java/org/opentripplanner/raptor/RaptorService.java +++ b/src/main/java/org/opentripplanner/raptor/RaptorService.java @@ -71,7 +71,7 @@ private RaptorResponse routeUsingStdWorker( var worker = config.createStdWorker(transitData, request); var result = worker.route(); var arrivals = new DefaultStopArrivals(result); - return new RaptorResponse<>(result.extractPaths(), arrivals, request, request); + return new RaptorResponse<>(result.extractPaths(), arrivals, request, false); } private static void logRequest(RaptorRequest request) { diff --git a/src/main/java/org/opentripplanner/raptor/api/path/PathStringBuilder.java b/src/main/java/org/opentripplanner/raptor/api/path/PathStringBuilder.java index 4cf13e362fd..b96d1a96f14 100644 --- a/src/main/java/org/opentripplanner/raptor/api/path/PathStringBuilder.java +++ b/src/main/java/org/opentripplanner/raptor/api/path/PathStringBuilder.java @@ -119,8 +119,8 @@ public PathStringBuilder numberOfTransfers(int nTransfers) { : this; } - public PathStringBuilder summary(int c1) { - return summaryStart().c1(c1).summaryEnd(); + public PathStringBuilder summary(int c1, int c2) { + return summaryStart().c1(c1).c2(c2).summaryEnd(); } public PathStringBuilder summary(int startTime, int endTime, int nTransfers, int c1, int c2) { diff --git a/src/main/java/org/opentripplanner/raptor/api/path/RaptorPath.java b/src/main/java/org/opentripplanner/raptor/api/path/RaptorPath.java index 36caaf856e8..ca67599e262 100644 --- a/src/main/java/org/opentripplanner/raptor/api/path/RaptorPath.java +++ b/src/main/java/org/opentripplanner/raptor/api/path/RaptorPath.java @@ -3,6 +3,7 @@ import java.util.List; import java.util.stream.Stream; import javax.annotation.Nullable; +import org.opentripplanner.raptor.api.model.RaptorConstants; import org.opentripplanner.raptor.api.model.RaptorTripSchedule; import org.opentripplanner.raptor.api.model.RelaxFunction; @@ -56,8 +57,15 @@ public interface RaptorPath extends Comparable transitPriorityCalculator() { return Optional.ofNullable(transitPriorityCalculator); } @@ -85,8 +76,8 @@ public List passThroughPoints() { } /** - * Whether to accept non-optimal trips if they are close enough - if and only if they represent an - * optimal path for their given iteration. In other words this slack only relaxes the pareto + * Whether to accept non-optimal trips if they are close enough - if and only if they represent + * an optimal path for their given iteration. In other words this slack only relaxes the pareto * comparison at the destination. *

* Let {@code c} be the existing minimum pareto optimal cost to beat. Then a trip with cost @@ -102,8 +93,9 @@ public List passThroughPoints() { * is replaced by {@link #relaxC1()}. This parameter is ignored if {@link #relaxC1()} exist. */ @Deprecated - public Optional relaxCostAtDestination() { - return Optional.ofNullable(relaxCostAtDestination); + @Nullable + public Double relaxCostAtDestination() { + return relaxCostAtDestination; } @Override diff --git a/src/main/java/org/opentripplanner/raptor/api/response/RaptorResponse.java b/src/main/java/org/opentripplanner/raptor/api/response/RaptorResponse.java index 9cee0357d9d..82c0c06d0cd 100644 --- a/src/main/java/org/opentripplanner/raptor/api/response/RaptorResponse.java +++ b/src/main/java/org/opentripplanner/raptor/api/response/RaptorResponse.java @@ -17,20 +17,20 @@ public class RaptorResponse { private final Collection> paths; - private final RaptorRequest requestOriginal; private final RaptorRequest requestUsed; private final StopArrivals arrivals; + private final boolean heuristicPathExist; public RaptorResponse( Collection> paths, StopArrivals arrivals, - RaptorRequest requestOriginal, - RaptorRequest requestUsed + RaptorRequest requestUsed, + boolean heuristicPathExist ) { this.paths = paths; this.arrivals = arrivals; - this.requestOriginal = requestOriginal; this.requestUsed = requestUsed; + this.heuristicPathExist = heuristicPathExist; } /** @@ -52,13 +52,6 @@ public StopArrivals getArrivals() { return arrivals; } - /** - * The original request issued to perform the travel search. - */ - public RaptorRequest requestOriginal() { - return requestOriginal; - } - /** * The actual request used to perform the travel search. In the case of a multi-criteria search, * heuristics is used to optimize the search and the request is changed to account for this. Also, @@ -69,12 +62,20 @@ public RaptorRequest requestUsed() { return requestUsed; } + /** + * Return {@code true} if the heuristic and the main search does not find any connections. + * Searching again with another time/search-window will not produce any results. There is no paths + * in the set of days provided in the transit data with the request usd. + */ + public boolean noConnectionFound() { + return paths.isEmpty() && !heuristicPathExist; + } + @Override public String toString() { return ToStringBuilder .of(RaptorResponse.class) .addObj("paths", paths) - .addObj("requestOriginal", requestOriginal) .addObj("requestUsed", requestUsed) .toString(); } diff --git a/src/main/java/org/opentripplanner/raptor/path/PathBuilder.java b/src/main/java/org/opentripplanner/raptor/path/PathBuilder.java index c046a8f240d..7612cc0b3ba 100644 --- a/src/main/java/org/opentripplanner/raptor/path/PathBuilder.java +++ b/src/main/java/org/opentripplanner/raptor/path/PathBuilder.java @@ -182,6 +182,10 @@ public int c2() { return tail.isC2Set() ? tail.c2() : c2; } + public boolean isC2Set() { + return tail.isC2Set() || c2 != RaptorConstants.NOT_SET; + } + public RaptorPath build() { updateAggregatedFields(); var pathLegs = createPathLegs(costCalculator, slackProvider); diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/SystemErrDebugLogger.java b/src/main/java/org/opentripplanner/raptor/rangeraptor/SystemErrDebugLogger.java index 8c35f103106..060d3a2e018 100644 --- a/src/main/java/org/opentripplanner/raptor/rangeraptor/SystemErrDebugLogger.java +++ b/src/main/java/org/opentripplanner/raptor/rangeraptor/SystemErrDebugLogger.java @@ -219,7 +219,7 @@ private void print(PatternRideView p, String action) { } private String path(ArrivalView a) { - return path(a, new PathStringBuilder(null)).summary(a.c1()).toString(); + return path(a, new PathStringBuilder(null)).summary(a.c1(), a.c2()).toString(); } private PathStringBuilder path(ArrivalView a, PathStringBuilder buf) { diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/context/SearchContext.java b/src/main/java/org/opentripplanner/raptor/rangeraptor/context/SearchContext.java index eda2cabc0a1..1706c879a2c 100644 --- a/src/main/java/org/opentripplanner/raptor/rangeraptor/context/SearchContext.java +++ b/src/main/java/org/opentripplanner/raptor/rangeraptor/context/SearchContext.java @@ -1,5 +1,9 @@ package org.opentripplanner.raptor.rangeraptor.context; +import static org.opentripplanner.raptor.rangeraptor.internalapi.ParetoSetTime.USE_ARRIVAL_TIME; +import static org.opentripplanner.raptor.rangeraptor.internalapi.ParetoSetTime.USE_DEPARTURE_TIME; +import static org.opentripplanner.raptor.rangeraptor.internalapi.ParetoSetTime.USE_TIMETABLE; + import java.util.Collection; import java.util.HashMap; import java.util.List; @@ -20,6 +24,7 @@ import org.opentripplanner.raptor.api.request.RaptorTuningParameters; import org.opentripplanner.raptor.api.request.SearchParams; import org.opentripplanner.raptor.rangeraptor.debug.DebugHandlerFactory; +import org.opentripplanner.raptor.rangeraptor.internalapi.ParetoSetTime; import org.opentripplanner.raptor.rangeraptor.internalapi.RoundProvider; import org.opentripplanner.raptor.rangeraptor.internalapi.SlackProvider; import org.opentripplanner.raptor.rangeraptor.internalapi.WorkerLifeCycle; @@ -218,6 +223,13 @@ public TimeBasedBoardingSupport createTimeBasedBoardingSupport() { ); } + /** + * Resolve which pareto-set time config to use. + */ + public ParetoSetTime paretoSetTimeConfig() { + return paretoSetTimeConfig(searchParams(), searchDirection()); + } + /** * The multi-criteria state can handle multiple access/egress paths to a single stop, but the * Standard and BestTime states do not. To get a deterministic behaviour we filter the paths and @@ -307,4 +319,17 @@ private static EgressPaths egressPaths(RaptorRequest request) { var paths = forward ? params.egressPaths() : params.accessPaths(); return EgressPaths.create(paths, request.profile()); } + + static ParetoSetTime paretoSetTimeConfig( + SearchParams searchParams, + SearchDirection searchDirection + ) { + if (searchParams.timetable()) { + return USE_TIMETABLE; + } + boolean preferLatestDeparture = + searchParams.preferLateArrival() != searchDirection.isInReverse(); + + return preferLatestDeparture ? USE_DEPARTURE_TIME : USE_ARRIVAL_TIME; + } } diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/internalapi/ParetoSetCost.java b/src/main/java/org/opentripplanner/raptor/rangeraptor/internalapi/ParetoSetCost.java new file mode 100644 index 00000000000..7ae3706bb4e --- /dev/null +++ b/src/main/java/org/opentripplanner/raptor/rangeraptor/internalapi/ParetoSetCost.java @@ -0,0 +1,48 @@ +package org.opentripplanner.raptor.rangeraptor.internalapi; + +/** + * These are the different cost configuration Raptor support. Each configuration will + * be used to change the pareto-function used to compare arrivals and paths. We add + * new values here when needed by a new use-case. + */ +public enum ParetoSetCost { + /** + * Cost is not used. + */ + NONE, + /** + * One cost parameter is used. A small c1 value is better than a large value. + */ + USE_C1, + /** + * Same as {@link #USE_C1}, but the relax function is used to relax the cost at the destination. + * DO not use this! This will be removed as soon as the Vy, Entur, Norway has migrated off + * this feature. + */ + @Deprecated + USE_C1_RELAX_DESTINATION, + /** + * Use both c1 and c2 in the pareto function. A small value is better than a large one. + */ + USE_C1_AND_C2, + /** + * Use c1 in the pareto function, but relax c1 is c2 is optimal. This allows slightly worse + * c1 values if a path is considered better based on the c2 value. Another way of looking at + * this, is that all paths are grouped by the c2 value. When two paths are compared inside a group + * the normal c1 comparison is used, and when comparing paths from different groups the relaxed + * c1 comparison is used. + */ + USE_C1_RELAXED_IF_C2_IS_OPTIMAL; + + public boolean includeC1() { + return this != NONE; + } + + /** + * Use c2 as input to the pareto function. The c2 value is used as a criteria, or it is used + * to modify the function ({@link #USE_C1_RELAXED_IF_C2_IS_OPTIMAL}). + */ + public boolean includeC2() { + return this == USE_C1_AND_C2 || this == USE_C1_RELAXED_IF_C2_IS_OPTIMAL; + } +} diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/internalapi/ParetoSetTime.java b/src/main/java/org/opentripplanner/raptor/rangeraptor/internalapi/ParetoSetTime.java new file mode 100644 index 00000000000..c0c6f7f08e1 --- /dev/null +++ b/src/main/java/org/opentripplanner/raptor/rangeraptor/internalapi/ParetoSetTime.java @@ -0,0 +1,21 @@ +package org.opentripplanner.raptor.rangeraptor.internalapi; + +/** + * These are the different time configurations Raptor supports. Each configuration will + * be used to change the pareto-function. + */ +public enum ParetoSetTime { + /** + * Uses iteration-departure-time and arrival-time as criteria in pareto function. Note! + * iteration-departure-time is slightly different from the more precise departure-time. + */ + USE_TIMETABLE, + /** + * Uses arrival-time as criteria in pareto function. + */ + USE_ARRIVAL_TIME, + /** + * Uses departure-time as criteria in pareto function. + */ + USE_DEPARTURE_TIME, +} diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/configure/McRangeRaptorConfig.java b/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/configure/McRangeRaptorConfig.java index 649737bc42f..e7aa07fb914 100644 --- a/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/configure/McRangeRaptorConfig.java +++ b/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/configure/McRangeRaptorConfig.java @@ -9,6 +9,7 @@ import org.opentripplanner.raptor.api.request.RaptorTransitPriorityGroupCalculator; import org.opentripplanner.raptor.rangeraptor.context.SearchContext; import org.opentripplanner.raptor.rangeraptor.internalapi.Heuristics; +import org.opentripplanner.raptor.rangeraptor.internalapi.ParetoSetCost; import org.opentripplanner.raptor.rangeraptor.internalapi.PassThroughPointsService; import org.opentripplanner.raptor.rangeraptor.internalapi.RaptorWorker; import org.opentripplanner.raptor.rangeraptor.internalapi.RaptorWorkerState; @@ -157,7 +158,8 @@ private > ParetoSet createPatternRideParetoSet( private DestinationArrivalPaths createDestinationArrivalPaths() { if (paths == null) { - paths = pathConfig.createDestArrivalPaths(true, includeC2() ? dominanceFunctionC2() : null); + var c2Comp = includeC2() ? dominanceFunctionC2() : null; + paths = pathConfig.createDestArrivalPaths(resolveCostConfig(), c2Comp); } return paths; } @@ -209,4 +211,17 @@ private boolean isPassThrough() { private boolean isTransitPriority() { return mcRequest().transitPriorityCalculator().isPresent(); } + + private ParetoSetCost resolveCostConfig() { + if (isTransitPriority()) { + return ParetoSetCost.USE_C1_RELAXED_IF_C2_IS_OPTIMAL; + } + if (isPassThrough()) { + return ParetoSetCost.USE_C1_AND_C2; + } + if (context.multiCriteria().relaxCostAtDestination() != null) { + return ParetoSetCost.USE_C1_RELAX_DESTINATION; + } + return ParetoSetCost.USE_C1; + } } diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/path/PathParetoSetComparators.java b/src/main/java/org/opentripplanner/raptor/rangeraptor/path/PathParetoSetComparators.java index 220e014b836..00ea6d11fe5 100644 --- a/src/main/java/org/opentripplanner/raptor/rangeraptor/path/PathParetoSetComparators.java +++ b/src/main/java/org/opentripplanner/raptor/rangeraptor/path/PathParetoSetComparators.java @@ -7,12 +7,15 @@ import static org.opentripplanner.raptor.api.path.RaptorPath.compareIterationDepartureTime; import static org.opentripplanner.raptor.api.path.RaptorPath.compareNumberOfTransfers; +import java.util.Objects; import javax.annotation.Nonnull; import org.opentripplanner.raptor.api.model.DominanceFunction; import org.opentripplanner.raptor.api.model.RaptorTripSchedule; import org.opentripplanner.raptor.api.model.RelaxFunction; import org.opentripplanner.raptor.api.model.SearchDirection; import org.opentripplanner.raptor.api.path.RaptorPath; +import org.opentripplanner.raptor.rangeraptor.internalapi.ParetoSetCost; +import org.opentripplanner.raptor.rangeraptor.internalapi.ParetoSetTime; import org.opentripplanner.raptor.util.paretoset.ParetoComparator; /** @@ -25,6 +28,14 @@ *

  • Number of transfers
  • *
  • Total travel duration time
  • * + * Optional features are : + *
      + *
    • Prefer late arrival - arriveBy search
    • + *
    • Include c1 - include c1 in pareto function (generalized-cost).
    • + *
    • Include c2 - include c2 in pareto function (custom criteria).
    • + *
    • Relax c1 - accept c1 values which is slightly worse than the best result.
    • + *
    • Relax c1, if c2 is optimal
    • + *
    * The {@code travelDuration} is added as a criteria to the pareto comparator in addition to the * parameters used for each stop arrivals. The {@code travelDuration} is only needed at the * destination, because Range Raptor works in iterations backwards in time. @@ -36,98 +47,52 @@ private PathParetoSetComparators() {} /** * Create pareto-set comparison function. - * @param includeC1 Whether to include generalized cost as a criteria. - * @param includeTimetable // TODO: 2023-07-31 What is this parameter doing exactly? - * @param preferLateArrival // TODO: 2023-07-31 What is this parameter doing exactly? - * @param relaxC1 Relax function for the generalized cost - * @param c2Comp Dominance function for accumulated criteria TWO. If function is null, C2 will - * not be included in the comparison. + * + * @param timeConfig Which time information (arrival-time, departure-time, or timetable) to include in comparator. + * @param costConfig Supported configurations of c1, c2 and relaxed cost(c1). + * @param relaxC1 Relax function for the generalized cost + * @param c2Comp Dominance function for accumulated criteria TWO. If function is null, + * C2 will not be included in the comparison. */ public static ParetoComparator> paretoComparator( - final boolean includeC1, - final boolean includeTimetable, - final boolean preferLateArrival, - final SearchDirection searchDirection, - final RelaxFunction relaxC1, - final DominanceFunction c2Comp + ParetoSetTime timeConfig, + ParetoSetCost costConfig, + RelaxFunction relaxC1, + DominanceFunction c2Comp ) { - /* - * TODO pass-through: I would like to see if we can refactor this with something like this, and - * still get the same performance: - * - * if(c2Comp == null) { - * return paretoComparator(...); - * } - * else { - * return paretoComparator(...) || c2Comp.leftDominateRight(l.c2(), r.c2()); - * } - */ - boolean includeRelaxedCost = includeC1 && !relaxC1.isNormal(); - boolean preferLatestDeparture = preferLateArrival != searchDirection.isInReverse(); - - if (includeRelaxedCost) { - if (includeTimetable) { - if (c2Comp != null) { - return comparatorTimetableAndRelaxedC1AndC2(relaxC1, c2Comp); - } else { - return comparatorTimetableAndRelaxedC1(relaxC1); - } - } - if (preferLateArrival) { - if (c2Comp != null) { - return comparatorDepartureTimeAndRelaxedC1AndC2(relaxC1, c2Comp); - } else { - return comparatorDepartureTimeAndRelaxedC1(relaxC1); - } - } else { - if (c2Comp != null) { - return comparatorArrivalTimeAndRelaxedC1AndC2(relaxC1, c2Comp); - } else { - return comparatorArrivalTimeAndRelaxedC1(relaxC1); - } - } - } + Objects.requireNonNull(timeConfig); + Objects.requireNonNull(costConfig); - if (includeC1) { - if (includeTimetable) { - if (c2Comp != null) { - return comparatorTimetableAndC1AndC2(c2Comp); - } else { - return comparatorTimetableAndC1(); - } - } - if (preferLatestDeparture) { - if (c2Comp != null) { - return comparatorDepartureTimeAndC1AndC2(c2Comp); - } else { - return comparatorDepartureTimeAndC1(); - } - } - if (c2Comp != null) { - return comparatorWithC1AndC2(c2Comp); - } else { - return comparatorWithC1(); - } - } - - if (includeTimetable) { - if (c2Comp != null) { - return comparatorTimetableAndC2(c2Comp); - } else { - return comparatorTimetable(); - } - } - if (preferLatestDeparture) { - if (c2Comp != null) { - return comparatorStandardDepartureTimeAndC2(c2Comp); - } else { - return comparatorStandardDepartureTime(); - } - } - if (c2Comp != null) { - return comparatorStandardArrivalTimeAndC2(c2Comp); - } - return comparatorStandardArrivalTime(); + return switch (costConfig) { + case NONE -> switch (timeConfig) { + case USE_TIMETABLE -> comparatorTimetable(); + case USE_ARRIVAL_TIME -> comparatorStandardArrivalTime(); + case USE_DEPARTURE_TIME -> comparatorStandardDepartureTime(); + }; + case USE_C1 -> switch (timeConfig) { + case USE_TIMETABLE -> comparatorTimetableAndC1(); + case USE_ARRIVAL_TIME -> comparatorArrivalTimeAndC1(); + case USE_DEPARTURE_TIME -> comparatorDepartureTimeAndC1(); + }; + case USE_C1_AND_C2 -> switch (timeConfig) { + case USE_TIMETABLE -> comparatorTimetableAndC1AndC2(c2Comp); + case USE_ARRIVAL_TIME -> comparatorWithC1AndC2(c2Comp); + case USE_DEPARTURE_TIME -> comparatorDepartureTimeAndC1AndC2(c2Comp); + }; + case USE_C1_RELAXED_IF_C2_IS_OPTIMAL -> switch (timeConfig) { + case USE_TIMETABLE -> comparatorTimetableAndRelaxedC1IfC2IsOptimal(relaxC1, c2Comp); + case USE_ARRIVAL_TIME -> comparatorArrivalTimeAndRelaxedC1IfC2IsOptimal(relaxC1, c2Comp); + case USE_DEPARTURE_TIME -> comparatorDepartureTimeAndRelaxedC1IfC2IsOptimal( + relaxC1, + c2Comp + ); + }; + case USE_C1_RELAX_DESTINATION -> switch (timeConfig) { + case USE_TIMETABLE -> comparatorTimetableAndRelaxedC1(relaxC1); + case USE_ARRIVAL_TIME -> comparatorArrivalTimeAndRelaxedC1(relaxC1); + case USE_DEPARTURE_TIME -> comparatorDepartureTimeAndRelaxedC1(relaxC1); + }; + }; } private static < @@ -136,34 +101,12 @@ > ParetoComparator> comparatorStandardArrivalTime() { return (l, r) -> compareArrivalTime(l, r) || compareNumberOfTransfers(l, r); } - private static < - T extends RaptorTripSchedule - > ParetoComparator> comparatorStandardArrivalTimeAndC2( - @Nonnull final DominanceFunction c2Comp - ) { - return (l, r) -> - compareArrivalTime(l, r) || - compareNumberOfTransfers(l, r) || - c2Comp.leftDominateRight(l.c2(), r.c2()); - } - private static < T extends RaptorTripSchedule > ParetoComparator> comparatorStandardDepartureTime() { return (l, r) -> compareDepartureTime(l, r) || compareNumberOfTransfers(l, r); } - private static < - T extends RaptorTripSchedule - > ParetoComparator> comparatorStandardDepartureTimeAndC2( - @Nonnull final DominanceFunction c2Comp - ) { - return (l, r) -> - compareDepartureTime(l, r) || - compareNumberOfTransfers(l, r) || - c2Comp.leftDominateRight(l.c2(), r.c2()); - } - private static < T extends RaptorTripSchedule > ParetoComparator> comparatorTimetable() { @@ -173,18 +116,6 @@ > ParetoComparator> comparatorTimetable() { compareNumberOfTransfers(l, r); } - private static < - T extends RaptorTripSchedule - > ParetoComparator> comparatorTimetableAndC2( - @Nonnull final DominanceFunction c2Comp - ) { - return (l, r) -> - compareIterationDepartureTime(l, r) || - compareArrivalTime(l, r) || - compareNumberOfTransfers(l, r) || - c2Comp.leftDominateRight(l.c2(), r.c2()); - } - private static < T extends RaptorTripSchedule > ParetoComparator> comparatorTimetableAndC1() { @@ -209,7 +140,9 @@ > ParetoComparator> comparatorTimetableAndRelaxedC1( compareC1(relaxCost, l, r); } - private static ParetoComparator> comparatorWithC1() { + private static < + T extends RaptorTripSchedule + > ParetoComparator> comparatorArrivalTimeAndC1() { return (l, r) -> compareArrivalTime(l, r) || compareNumberOfTransfers(l, r) || @@ -230,7 +163,7 @@ > ParetoComparator> comparatorDepartureTimeAndC1() { private static < T extends RaptorTripSchedule > ParetoComparator> comparatorArrivalTimeAndRelaxedC1( - @Nonnull final RelaxFunction relaxCost + @Nonnull RelaxFunction relaxCost ) { return (l, r) -> compareArrivalTime(l, r) || @@ -242,7 +175,7 @@ > ParetoComparator> comparatorArrivalTimeAndRelaxedC1( private static < T extends RaptorTripSchedule > ParetoComparator> comparatorDepartureTimeAndRelaxedC1( - @Nonnull final RelaxFunction relaxCost + @Nonnull RelaxFunction relaxCost ) { return (l, r) -> compareDepartureTime(l, r) || @@ -254,7 +187,7 @@ > ParetoComparator> comparatorDepartureTimeAndRelaxedC1( private static < T extends RaptorTripSchedule > ParetoComparator> comparatorTimetableAndC1AndC2( - @Nonnull final DominanceFunction c2Comp + @Nonnull DominanceFunction c2Comp ) { return (l, r) -> compareIterationDepartureTime(l, r) || @@ -267,22 +200,21 @@ > ParetoComparator> comparatorTimetableAndC1AndC2( private static < T extends RaptorTripSchedule - > ParetoComparator> comparatorTimetableAndRelaxedC1AndC2( - @Nonnull final RelaxFunction relaxCost, - @Nonnull final DominanceFunction c2Comp + > ParetoComparator> comparatorTimetableAndRelaxedC1IfC2IsOptimal( + @Nonnull RelaxFunction relaxCost, + @Nonnull DominanceFunction c2Comp ) { return (l, r) -> compareIterationDepartureTime(l, r) || compareArrivalTime(l, r) || compareNumberOfTransfers(l, r) || compareDuration(l, r) || - compareC1(relaxCost, l, r) || - c2Comp.leftDominateRight(l.c2(), r.c2()); + compareC1RelaxedIfC2IsOptimal(l, r, relaxCost, c2Comp); } private static < T extends RaptorTripSchedule - > ParetoComparator> comparatorWithC1AndC2(@Nonnull final DominanceFunction c2Comp) { + > ParetoComparator> comparatorWithC1AndC2(@Nonnull DominanceFunction c2Comp) { return (l, r) -> compareArrivalTime(l, r) || compareNumberOfTransfers(l, r) || @@ -294,7 +226,7 @@ > ParetoComparator> comparatorWithC1AndC2(@Nonnull final Dominance private static < T extends RaptorTripSchedule > ParetoComparator> comparatorDepartureTimeAndC1AndC2( - @Nonnull final DominanceFunction c2Comp + @Nonnull DominanceFunction c2Comp ) { return (l, r) -> compareDepartureTime(l, r) || @@ -306,29 +238,36 @@ > ParetoComparator> comparatorDepartureTimeAndC1AndC2( private static < T extends RaptorTripSchedule - > ParetoComparator> comparatorArrivalTimeAndRelaxedC1AndC2( - @Nonnull final RelaxFunction relaxCost, - @Nonnull final DominanceFunction c2Comp + > ParetoComparator> comparatorArrivalTimeAndRelaxedC1IfC2IsOptimal( + @Nonnull RelaxFunction relaxCost, + @Nonnull DominanceFunction c2Comp ) { return (l, r) -> compareArrivalTime(l, r) || compareNumberOfTransfers(l, r) || compareDuration(l, r) || - compareC1(relaxCost, l, r) || - c2Comp.leftDominateRight(l.c2(), r.c2()); + compareC1RelaxedIfC2IsOptimal(l, r, relaxCost, c2Comp); } private static < T extends RaptorTripSchedule - > ParetoComparator> comparatorDepartureTimeAndRelaxedC1AndC2( - @Nonnull final RelaxFunction relaxCost, - @Nonnull final DominanceFunction c2Comp + > ParetoComparator> comparatorDepartureTimeAndRelaxedC1IfC2IsOptimal( + @Nonnull RelaxFunction relaxCost, + @Nonnull DominanceFunction c2Comp ) { return (l, r) -> compareDepartureTime(l, r) || compareNumberOfTransfers(l, r) || compareDuration(l, r) || - compareC1(relaxCost, l, r) || - c2Comp.leftDominateRight(l.c2(), r.c2()); + compareC1RelaxedIfC2IsOptimal(l, r, relaxCost, c2Comp); + } + + private static boolean compareC1RelaxedIfC2IsOptimal( + @Nonnull RaptorPath l, + @Nonnull RaptorPath r, + @Nonnull RelaxFunction relaxCost, + @Nonnull DominanceFunction c2Comp + ) { + return c2Comp.leftDominateRight(l.c2(), r.c2()) ? compareC1(relaxCost, l, r) : compareC1(l, r); } } diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/path/configure/PathConfig.java b/src/main/java/org/opentripplanner/raptor/rangeraptor/path/configure/PathConfig.java index 4403e72375c..89b2f447ca4 100644 --- a/src/main/java/org/opentripplanner/raptor/rangeraptor/path/configure/PathConfig.java +++ b/src/main/java/org/opentripplanner/raptor/rangeraptor/path/configure/PathConfig.java @@ -3,12 +3,16 @@ import static org.opentripplanner.raptor.rangeraptor.path.PathParetoSetComparators.paretoComparator; import org.opentripplanner.raptor.api.model.DominanceFunction; +import org.opentripplanner.raptor.api.model.GeneralizedCostRelaxFunction; import org.opentripplanner.raptor.api.model.RaptorTripSchedule; +import org.opentripplanner.raptor.api.model.RelaxFunction; import org.opentripplanner.raptor.api.model.SearchDirection; import org.opentripplanner.raptor.api.path.RaptorPath; import org.opentripplanner.raptor.api.path.RaptorStopNameResolver; import org.opentripplanner.raptor.api.request.RaptorProfile; import org.opentripplanner.raptor.rangeraptor.context.SearchContext; +import org.opentripplanner.raptor.rangeraptor.internalapi.ParetoSetCost; +import org.opentripplanner.raptor.rangeraptor.internalapi.ParetoSetTime; import org.opentripplanner.raptor.rangeraptor.internalapi.WorkerLifeCycle; import org.opentripplanner.raptor.rangeraptor.path.DestinationArrivalPaths; import org.opentripplanner.raptor.rangeraptor.path.ForwardPathMapper; @@ -35,23 +39,26 @@ public PathConfig(SearchContext context) { this.ctx = context; } + public DestinationArrivalPaths createDestArrivalPathsStdSearch() { + return createDestArrivalPaths(ParetoSetCost.NONE, DominanceFunction.noop()); + } + /** * Create a new {@link DestinationArrivalPaths}. - * @param includeC1Cost whether to include generalized cost in the pareto set criteria. - * It will be generated for each leg and a total for the path. + * @param costConfig Supported configurations of c1, c2 and relaxed cost(c1). * @param c2Comp c2 comparator function to be used in the pareto set criteria. If c2 comparator is null * then no c2 comparison will be used. */ public DestinationArrivalPaths createDestArrivalPaths( - boolean includeC1Cost, - final DominanceFunction c2Comp + ParetoSetCost costConfig, + DominanceFunction c2Comp ) { return new DestinationArrivalPaths<>( - createPathParetoComparator(includeC1Cost, c2Comp), + createPathParetoComparator(costConfig, c2Comp), ctx.calculator(), - includeC1Cost ? ctx.costCalculator() : null, + costConfig.includeC1() ? ctx.costCalculator() : null, ctx.slackProvider(), - createPathMapper(includeC1Cost), + createPathMapper(costConfig.includeC1()), ctx.debugFactory(), ctx.stopNameResolver(), ctx.lifeCycle() @@ -61,17 +68,30 @@ public DestinationArrivalPaths createDestArrivalPaths( /* private members */ private ParetoComparator> createPathParetoComparator( - boolean includeC1, - final DominanceFunction c2Comp + ParetoSetCost costConfig, + DominanceFunction c2Comp ) { - return paretoComparator( - includeC1, - ctx.searchParams().timetable(), - ctx.searchParams().preferLateArrival(), - ctx.searchDirection(), - ctx.multiCriteria().relaxC1AtDestination(), - c2Comp - ); + // This code goes away when the USE_C1_RELAX_DESTINATION is deleted + var relaxC1 = + switch (costConfig) { + case USE_C1_RELAXED_IF_C2_IS_OPTIMAL -> ctx.multiCriteria().relaxC1(); + case USE_C1_RELAX_DESTINATION -> GeneralizedCostRelaxFunction.of( + ctx.multiCriteria().relaxCostAtDestination() + ); + default -> RelaxFunction.NORMAL; + }; + + return paretoComparator(paretoSetTimeConfig(), costConfig, relaxC1, c2Comp); + } + + private ParetoSetTime paretoSetTimeConfig() { + boolean preferLatestDeparture = + ctx.searchParams().preferLateArrival() != ctx.searchDirection().isInReverse(); + + ParetoSetTime timeConfig = ctx.searchParams().timetable() + ? ParetoSetTime.USE_TIMETABLE + : (preferLatestDeparture ? ParetoSetTime.USE_DEPARTURE_TIME : ParetoSetTime.USE_ARRIVAL_TIME); + return timeConfig; } private PathMapper createPathMapper(boolean includeCost) { diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/configure/StdRangeRaptorConfig.java b/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/configure/StdRangeRaptorConfig.java index d3f57c9443f..6e0c3ee5afd 100644 --- a/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/configure/StdRangeRaptorConfig.java +++ b/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/configure/StdRangeRaptorConfig.java @@ -6,9 +6,9 @@ import java.util.HashSet; import java.util.Set; import org.opentripplanner.raptor.api.model.RaptorTripSchedule; -import org.opentripplanner.raptor.api.model.RelaxFunction; import org.opentripplanner.raptor.rangeraptor.context.SearchContext; import org.opentripplanner.raptor.rangeraptor.internalapi.Heuristics; +import org.opentripplanner.raptor.rangeraptor.internalapi.ParetoSetCost; import org.opentripplanner.raptor.rangeraptor.internalapi.RaptorWorkerResult; import org.opentripplanner.raptor.rangeraptor.internalapi.RaptorWorkerState; import org.opentripplanner.raptor.rangeraptor.internalapi.RoutingStrategy; @@ -174,7 +174,7 @@ private StopArrivalsState wrapStopArrivalsStateWithDebugger(StopArrivalsState } private DestinationArrivalPaths destinationArrivalPaths() { - var destinationArrivalPaths = pathConfig.createDestArrivalPaths(false, null); + var destinationArrivalPaths = pathConfig.createDestArrivalPathsStdSearch(); // Add egressArrivals to stops and bind them to the destination arrival paths. The // adapter notify the destination on each new egress stop arrival. @@ -244,25 +244,15 @@ private BestNumberOfTransfers resolveBestNumberOfTransfers() { } private UnknownPathFactory unknownPathFactory() { - return oneOf( - new UnknownPathFactory<>( - resolveBestTimes(), - resolveBestNumberOfTransfers(), - ctx.calculator(), - ctx.slackProvider().transferSlack(), - ctx.egressPaths(), - MIN_TRAVEL_DURATION.is(ctx.profile()), - paretoComparator( - false, - ctx.searchParams().timetable(), - ctx.searchParams().preferLateArrival(), - ctx.searchDirection(), - RelaxFunction.NORMAL, - null - ), - ctx.lifeCycle() - ), - UnknownPathFactory.class + return new UnknownPathFactory<>( + resolveBestTimes(), + resolveBestNumberOfTransfers(), + ctx.calculator(), + ctx.slackProvider().transferSlack(), + ctx.egressPaths(), + MIN_TRAVEL_DURATION.is(ctx.profile()), + paretoComparator(ctx.paretoSetTimeConfig(), ParetoSetCost.NONE, null, null), + ctx.lifeCycle() ); } diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/heuristics/HeuristicsAdapter.java b/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/heuristics/HeuristicsAdapter.java index ff38fff6d40..107d41208f4 100644 --- a/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/heuristics/HeuristicsAdapter.java +++ b/src/main/java/org/opentripplanner/raptor/rangeraptor/standard/heuristics/HeuristicsAdapter.java @@ -159,7 +159,8 @@ private int[] toIntArray(int size, int unreached, IntUnaryOperator supplier) { private record AggregatedResults( int minJourneyTravelDuration, int minJourneyNumOfTransfers, - int earliestArrivalTime + int earliestArrivalTime, + boolean reached ) { private static AggregatedResults create( TransitCalculator calculator, @@ -204,7 +205,8 @@ private static AggregatedResults create( return new AggregatedResults( bestJourneyTravelDuration, bestJourneyNumOfTransfers, - bestArrivalTime + bestArrivalTime, + bestArrivalTime != NOT_SET ); } } diff --git a/src/main/java/org/opentripplanner/raptor/service/RangeRaptorDynamicSearch.java b/src/main/java/org/opentripplanner/raptor/service/RangeRaptorDynamicSearch.java index fe8bb884912..fb96b7a8724 100644 --- a/src/main/java/org/opentripplanner/raptor/service/RangeRaptorDynamicSearch.java +++ b/src/main/java/org/opentripplanner/raptor/service/RangeRaptorDynamicSearch.java @@ -79,11 +79,11 @@ public RaptorResponse route() { return new RaptorResponse<>( Collections.emptyList(), null, - originalRequest, // If a trip exist(forward heuristics succeed), but is outside the calculated // search-window, then set the search-window params as if the request was - // performed. This enable the client to page to the next window - requestWithDynamicSearchParams(originalRequest) + // performed. This enables the client to page to the next window + requestWithDynamicSearchParams(originalRequest), + false ); } } @@ -146,8 +146,9 @@ private RaptorResponse createAndRunDynamicRRWorker(RaptorRequest request) return new RaptorResponse<>( result.extractPaths(), new DefaultStopArrivals(result), - originalRequest, - request + request, + // This method is not run unless the heuristic reached the destination + true ); } diff --git a/src/main/java/org/opentripplanner/raptor/spi/UnknownPath.java b/src/main/java/org/opentripplanner/raptor/spi/UnknownPath.java index b95417e86b6..de6a846f480 100644 --- a/src/main/java/org/opentripplanner/raptor/spi/UnknownPath.java +++ b/src/main/java/org/opentripplanner/raptor/spi/UnknownPath.java @@ -125,7 +125,7 @@ public String toString(RaptorStopNameResolver stopNameTranslator) { public String toString() { PathStringBuilder pathBuilder = new PathStringBuilder(null); if (departureTime == 0 && arrivalTime == 0) { - pathBuilder.summary(c1()); + pathBuilder.summary(c1(), c2()); } else { pathBuilder.summary(startTime(), endTime(), numberOfTransfers, c1(), c2()); } diff --git a/src/main/java/org/opentripplanner/routing/alertpatch/TransitAlert.java b/src/main/java/org/opentripplanner/routing/alertpatch/TransitAlert.java index 98127555e56..d5d260a8218 100644 --- a/src/main/java/org/opentripplanner/routing/alertpatch/TransitAlert.java +++ b/src/main/java/org/opentripplanner/routing/alertpatch/TransitAlert.java @@ -33,6 +33,7 @@ public class TransitAlert extends AbstractTransitEntity entities; @@ -52,6 +53,7 @@ public class TransitAlert extends AbstractTransitEntitynull + */ + @Nullable + public Integer version() { + return version; + } + public ZonedDateTime updatedTime() { return updatedTime; } @@ -195,6 +207,7 @@ public boolean sameAs(@Nonnull TransitAlert other) { Objects.equals(effect, other.effect) && Objects.equals(priority, other.priority) && Objects.equals(creationTime, other.creationTime) && + Objects.equals(version, other.version) && Objects.equals(updatedTime, other.updatedTime) && Objects.equals(siriCodespace, other.siriCodespace) && Objects.equals(entities, other.entities) && diff --git a/src/main/java/org/opentripplanner/routing/alertpatch/TransitAlertBuilder.java b/src/main/java/org/opentripplanner/routing/alertpatch/TransitAlertBuilder.java index fda6b571585..654a47fe12b 100644 --- a/src/main/java/org/opentripplanner/routing/alertpatch/TransitAlertBuilder.java +++ b/src/main/java/org/opentripplanner/routing/alertpatch/TransitAlertBuilder.java @@ -27,6 +27,7 @@ public class TransitAlertBuilder extends AbstractEntityBuilder entities = new HashSet<>(); private final List timePeriods = new ArrayList<>(); @@ -167,6 +168,15 @@ public TransitAlertBuilder withCreationTime(ZonedDateTime creationTime) { return this; } + public Integer version() { + return version; + } + + public TransitAlertBuilder withVersion(Integer version) { + this.version = version; + return this; + } + public ZonedDateTime updatedTime() { return updatedTime; } diff --git a/src/main/java/org/opentripplanner/routing/algorithm/mapping/RaptorPathToItineraryMapper.java b/src/main/java/org/opentripplanner/routing/algorithm/mapping/RaptorPathToItineraryMapper.java index a9b042083bf..fe20592576e 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/mapping/RaptorPathToItineraryMapper.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/mapping/RaptorPathToItineraryMapper.java @@ -153,6 +153,9 @@ else if (pathLeg.isTransferLeg()) { if (egressPathLeg.egress() instanceof DefaultAccessEgress ae) { itinerary.setAccessPenalty(ae.penalty()); } + if (path.isC2Set()) { + itinerary.setGeneralizedCost2(path.c2()); + } return itinerary; } diff --git a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/router/TransitRouter.java b/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/router/TransitRouter.java index f18aa056504..1b5c836c832 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/router/TransitRouter.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/router/TransitRouter.java @@ -229,7 +229,10 @@ private Collection fetchAccessEgresses(AccessEgressType typ RouteRequest accessRequest = request.clone(); if (type.isAccess()) { - accessRequest.journey().rental().setAllowArrivingInRentedVehicleAtDestination(false); + accessRequest.withPreferences(p -> { + p.withBike(b -> b.withRental(r -> r.withAllowArrivingInRentedVehicleAtDestination(false))); + p.withCar(c -> c.withRental(r -> r.withAllowArrivingInRentedVehicleAtDestination(false))); + }); } Duration durationLimit = accessRequest @@ -340,8 +343,7 @@ private void verifyAccessEgress(Collection access, Collection egress) { * origin and destination. */ private void checkIfTransitConnectionExists(RaptorResponse response) { - int searchWindowUsed = response.requestUsed().searchParams().searchWindowInSeconds(); - if (searchWindowUsed <= 0 && response.paths().isEmpty()) { + if (response.noConnectionFound()) { throw new RoutingValidationException( List.of(new RoutingError(RoutingErrorCode.NO_TRANSIT_CONNECTION, null)) ); diff --git a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/BinarySetOperator.java b/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/BinarySetOperator.java new file mode 100644 index 00000000000..35e5b8c0918 --- /dev/null +++ b/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/BinarySetOperator.java @@ -0,0 +1,20 @@ +package org.opentripplanner.routing.algorithm.raptoradapter.transit.request; + +/** + * Used to concatenate matches with either the logical "AND" or "OR" operator. + */ +enum BinarySetOperator { + AND("&"), + OR("|"); + + private final String token; + + BinarySetOperator(String token) { + this.token = token; + } + + @Override + public String toString() { + return token; + } +} diff --git a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/PriorityGroupConfigurator.java b/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/PriorityGroupConfigurator.java index ba9af45adba..25006af49d8 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/PriorityGroupConfigurator.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/PriorityGroupConfigurator.java @@ -23,8 +23,29 @@ */ public class PriorityGroupConfigurator { - private static final int BASE_GROUP_ID = TransitPriorityGroup32n.groupId(0); - private int groupIndexCounter = 0; + /** + * There are two ways we can treat the base (local-traffic) transit priority group: + *
      + *
    1. We can assign group id 1 (one) to the base group and it will be treated as any other group. + *
    2. We can assign group id 0 (zero) to the base and it will not be added to the set of groups + * a given path has. + *
    + * When we compare paths we compare sets of group ids. A set is dominating another set if it is + * a smaller subset or different from the other set. + *

    + * Example - base-group-id = 0 (zero) + *

    + * Let B be the base and G be concrete group. Then: (B) dominates (G), (G) dominates (B), (B) + * dominates (BG), but (G) does not dominate (BG). In other words, paths with only agency + * X (group G) is not given an advantage in the routing over paths with a combination of agency + * X (group G) and local traffic (group B). + *

    + * TODO: Experiment with base-group-id=0 and make it configurable. + */ + private static final int GROUP_INDEX_COUNTER_START = 1; + + private final int baseGroupId = TransitPriorityGroup32n.groupId(GROUP_INDEX_COUNTER_START); + private int groupIndexCounter = GROUP_INDEX_COUNTER_START; private final boolean enabled; private final PriorityGroupMatcher[] agencyMatchers; private final PriorityGroupMatcher[] globalMatchers; @@ -75,7 +96,7 @@ public static PriorityGroupConfigurator of( */ public int lookupTransitPriorityGroupId(RoutingTripPattern tripPattern) { if (!enabled || tripPattern == null) { - return BASE_GROUP_ID; + return baseGroupId; } var p = tripPattern.getPattern(); @@ -99,7 +120,11 @@ public int lookupTransitPriorityGroupId(RoutingTripPattern tripPattern) { } } // Fallback to base-group-id - return BASE_GROUP_ID; + return baseGroupId; + } + + public int baseGroupId() { + return baseGroupId; } private int nextGroupId() { diff --git a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/PriorityGroupMatcher.java b/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/PriorityGroupMatcher.java index dd7c1b46636..4d8a0475239 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/PriorityGroupMatcher.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/PriorityGroupMatcher.java @@ -1,5 +1,8 @@ package org.opentripplanner.routing.algorithm.raptoradapter.transit.request; +import static org.opentripplanner.routing.algorithm.raptoradapter.transit.request.BinarySetOperator.AND; +import static org.opentripplanner.routing.algorithm.raptoradapter.transit.request.BinarySetOperator.OR; + import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -59,7 +62,7 @@ public static PriorityGroupMatcher of(TransitPriorityGroupSelect select) { if (!select.routeIds().isEmpty()) { list.add(new IdMatcher("Route", select.routeIds(), p -> p.getRoute().getId())); } - return compositeOf(list); + return andOf(list); } static PriorityGroupMatcher[] of(Collection selectors) { @@ -70,15 +73,15 @@ static PriorityGroupMatcher[] of(Collection selector .toArray(PriorityGroupMatcher[]::new); } - private static String arrayToString(T[] values) { - return colToString(Arrays.asList(values)); + private static String arrayToString(BinarySetOperator op, T[] values) { + return colToString(op, Arrays.asList(values)); } - private static String colToString(Collection values) { - return values.stream().map(Objects::toString).collect(Collectors.joining(" | ")); + private static String colToString(BinarySetOperator op, Collection values) { + return values.stream().map(Objects::toString).collect(Collectors.joining(" " + op + " ")); } - private static PriorityGroupMatcher compositeOf(List list) { + private static PriorityGroupMatcher andOf(List list) { // Remove empty/noop matchers list = list.stream().filter(Predicate.not(PriorityGroupMatcher::isEmpty)).toList(); @@ -88,7 +91,7 @@ private static PriorityGroupMatcher compositeOf(List list) if (list.size() == 1) { return list.get(0); } - return new CompositeMatcher(list); + return new AndMatcher(list); } abstract boolean match(TripPattern pattern); @@ -112,7 +115,7 @@ boolean match(TripPattern pattern) { @Override public String toString() { - return "Mode(" + colToString(modes) + ')'; + return "Mode(" + colToString(OR, modes) + ')'; } } @@ -145,7 +148,7 @@ boolean match(TripPattern pattern) { @Override public String toString() { - return typeName + "Regexp(" + arrayToString(subModeRegexp) + ')'; + return typeName + "Regexp(" + arrayToString(OR, subModeRegexp) + ')'; } } @@ -172,35 +175,35 @@ boolean match(TripPattern pattern) { @Override public String toString() { - return typeName + "Id(" + colToString(ids) + ')'; + return typeName + "Id(" + colToString(OR, ids) + ')'; } } /** - * Take a list of matchers and provide a single interface. At least one matcher in the - * list must match for the composite matcher to return a match. + * Takes a list of matchers and provide a single interface. All matchers in the list must match + * for the composite matcher to return a match. */ - private static final class CompositeMatcher extends PriorityGroupMatcher { + private static final class AndMatcher extends PriorityGroupMatcher { private final PriorityGroupMatcher[] matchers; - public CompositeMatcher(List matchers) { + public AndMatcher(List matchers) { this.matchers = matchers.toArray(PriorityGroupMatcher[]::new); } @Override boolean match(TripPattern pattern) { for (var m : matchers) { - if (m.match(pattern)) { - return true; + if (!m.match(pattern)) { + return false; } } - return false; + return true; } @Override public String toString() { - return "(" + arrayToString(matchers) + ')'; + return "(" + arrayToString(AND, matchers) + ')'; } } } diff --git a/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/services/OptimizePathDomainService.java b/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/services/OptimizePathDomainService.java index 91b08212d2f..bfe5c3de841 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/services/OptimizePathDomainService.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/services/OptimizePathDomainService.java @@ -8,6 +8,7 @@ import java.util.Set; import java.util.stream.Collectors; import javax.annotation.Nullable; +import org.opentripplanner.raptor.api.model.RaptorConstants; import org.opentripplanner.raptor.api.model.RaptorTripSchedule; import org.opentripplanner.raptor.api.path.RaptorPath; import org.opentripplanner.raptor.api.path.RaptorStopNameResolver; @@ -115,6 +116,8 @@ public Set> findBestTransitPath(RaptorPath originalPath) { var filteredTails = filter.filterFinalResult(tails); + setC2IfNotSet(originalPath, filteredTails); + return filteredTails.stream().map(OptimizedPathTail::build).collect(toSet()); } @@ -255,4 +258,20 @@ private List>> sortTransfersOnArrivalStopPosInDecOrde ) .collect(Collectors.toList()); } + + /** + * Copy over c2 value from origin to new path if the c2 value is not generated by this service. + */ + private static void setC2IfNotSet( + RaptorPath originalPath, + Set> filteredTails + ) { + if (originalPath.isC2Set()) { + for (OptimizedPathTail tail : filteredTails) { + if (!tail.isC2Set()) { + tail.c2(originalPath.c2()); + } + } + } + } } diff --git a/src/main/java/org/opentripplanner/routing/api/request/preference/BikePreferences.java b/src/main/java/org/opentripplanner/routing/api/request/preference/BikePreferences.java index 115e1264036..5717876bbfc 100644 --- a/src/main/java/org/opentripplanner/routing/api/request/preference/BikePreferences.java +++ b/src/main/java/org/opentripplanner/routing/api/request/preference/BikePreferences.java @@ -30,6 +30,7 @@ public final class BikePreferences implements Serializable { private final int switchTime; private final Cost switchCost; private final VehicleParkingPreferences parking; + private final VehicleRentalPreferences rental; private final double stairsReluctance; private final BicycleOptimizeType optimizeType; private final TimeSlopeSafetyTriangle optimizeTriangle; @@ -43,6 +44,7 @@ private BikePreferences() { this.switchTime = 0; this.switchCost = Cost.ZERO; this.parking = VehicleParkingPreferences.DEFAULT; + this.rental = VehicleRentalPreferences.DEFAULT; this.optimizeType = BicycleOptimizeType.SAFE; this.optimizeTriangle = TimeSlopeSafetyTriangle.DEFAULT; // very high reluctance to carry the bike up/down a flight of stairs @@ -58,6 +60,7 @@ private BikePreferences(Builder builder) { this.switchTime = Units.duration(builder.switchTime); this.switchCost = builder.switchCost; this.parking = builder.parking; + this.rental = builder.rental; this.optimizeType = Objects.requireNonNull(builder.optimizeType); this.optimizeTriangle = Objects.requireNonNull(builder.optimizeTriangle); this.stairsReluctance = Units.reluctance(builder.stairsReluctance); @@ -126,6 +129,11 @@ public VehicleParkingPreferences parking() { return parking; } + /** Rental preferences that can be different per request */ + public VehicleRentalPreferences rental() { + return rental; + } + /** * The set of characteristics that the user wants to optimize for -- defaults to SAFE. */ @@ -155,6 +163,7 @@ public boolean equals(Object o) { switchTime == that.switchTime && switchCost.equals(that.switchCost) && parking.equals(that.parking) && + rental.equals(that.rental) && optimizeType == that.optimizeType && optimizeTriangle.equals(that.optimizeTriangle) && doubleEquals(stairsReluctance, that.stairsReluctance) @@ -172,6 +181,7 @@ public int hashCode() { switchTime, switchCost, parking, + rental, optimizeType, optimizeTriangle, stairsReluctance @@ -190,8 +200,10 @@ public String toString() { .addDurationSec("switchTime", switchTime, DEFAULT.switchTime) .addObj("switchCost", switchCost, DEFAULT.switchCost) .addObj("parking", parking, DEFAULT.parking) + .addObj("rental", rental, DEFAULT.rental) .addEnum("optimizeType", optimizeType, DEFAULT.optimizeType) .addObj("optimizeTriangle", optimizeTriangle, DEFAULT.optimizeTriangle) + .addNum("stairsReluctance", stairsReluctance, DEFAULT.stairsReluctance) .toString(); } @@ -207,6 +219,7 @@ public static class Builder { private int switchTime; private Cost switchCost; private VehicleParkingPreferences parking; + private VehicleRentalPreferences rental; private BicycleOptimizeType optimizeType; private TimeSlopeSafetyTriangle optimizeTriangle; @@ -222,6 +235,7 @@ public Builder(BikePreferences original) { this.switchTime = original.switchTime; this.switchCost = original.switchCost; this.parking = original.parking; + this.rental = original.rental; this.optimizeType = original.optimizeType; this.optimizeTriangle = original.optimizeTriangle; this.stairsReluctance = original.stairsReluctance; @@ -299,6 +313,11 @@ public Builder withParking(Consumer body) { return this; } + public Builder withRental(Consumer body) { + this.rental = ifNotNull(this.rental, original.rental).copyOf().apply(body).build(); + return this; + } + public BicycleOptimizeType optimizeType() { return optimizeType; } diff --git a/src/main/java/org/opentripplanner/routing/api/request/preference/CarPreferences.java b/src/main/java/org/opentripplanner/routing/api/request/preference/CarPreferences.java index 523e19afb70..6b103e8f3b7 100644 --- a/src/main/java/org/opentripplanner/routing/api/request/preference/CarPreferences.java +++ b/src/main/java/org/opentripplanner/routing/api/request/preference/CarPreferences.java @@ -24,6 +24,7 @@ public final class CarPreferences implements Serializable { private final double speed; private final double reluctance; private final VehicleParkingPreferences parking; + private final VehicleRentalPreferences rental; private final int pickupTime; private final Cost pickupCost; private final int dropoffTime; @@ -35,6 +36,7 @@ private CarPreferences() { this.speed = 40.0; this.reluctance = 2.0; this.parking = VehicleParkingPreferences.DEFAULT; + this.rental = VehicleRentalPreferences.DEFAULT; this.pickupTime = 60; this.pickupCost = Cost.costOfMinutes(2); this.dropoffTime = 120; @@ -46,6 +48,7 @@ private CarPreferences(Builder builder) { this.speed = Units.speed(builder.speed); this.reluctance = Units.reluctance(builder.reluctance); this.parking = builder.parking; + this.rental = builder.rental; this.pickupTime = Units.duration(builder.pickupTime); this.pickupCost = builder.pickupCost; this.dropoffTime = Units.duration(builder.dropoffTime); @@ -79,6 +82,11 @@ public VehicleParkingPreferences parking() { return parking; } + /** Rental preferences that can be different per request */ + public VehicleRentalPreferences rental() { + return rental; + } + /** Time of getting in/out of a carPickup (taxi) */ public int pickupTime() { return pickupTime; @@ -122,6 +130,7 @@ public boolean equals(Object o) { DoubleUtils.doubleEquals(that.speed, speed) && DoubleUtils.doubleEquals(that.reluctance, reluctance) && parking.equals(that.parking) && + rental.equals(that.rental) && pickupTime == that.pickupTime && pickupCost.equals(that.pickupCost) && dropoffTime == that.dropoffTime && @@ -136,6 +145,7 @@ public int hashCode() { speed, reluctance, parking, + rental, pickupTime, pickupCost, dropoffTime, @@ -151,6 +161,7 @@ public String toString() { .addNum("speed", speed, DEFAULT.speed) .addNum("reluctance", reluctance, DEFAULT.reluctance) .addObj("parking", parking, DEFAULT.parking) + .addObj("rental", rental, DEFAULT.rental) .addNum("pickupTime", pickupTime, DEFAULT.pickupTime) .addObj("pickupCost", pickupCost, DEFAULT.pickupCost) .addNum("dropoffTime", dropoffTime, DEFAULT.dropoffTime) @@ -166,6 +177,7 @@ public static class Builder { private double speed; private double reluctance; private VehicleParkingPreferences parking; + private VehicleRentalPreferences rental; private int pickupTime; private Cost pickupCost; private int dropoffTime; @@ -177,6 +189,7 @@ public Builder(CarPreferences original) { this.speed = original.speed; this.reluctance = original.reluctance; this.parking = original.parking; + this.rental = original.rental; this.pickupTime = original.pickupTime; this.pickupCost = original.pickupCost; this.dropoffTime = original.dropoffTime; @@ -203,6 +216,11 @@ public Builder withParking(Consumer body) { return this; } + public Builder withRental(Consumer body) { + this.rental = ifNotNull(this.rental, original.rental).copyOf().apply(body).build(); + return this; + } + public Builder withPickupTime(int pickupTime) { this.pickupTime = pickupTime; return this; diff --git a/src/main/java/org/opentripplanner/routing/api/request/preference/RoutingPreferences.java b/src/main/java/org/opentripplanner/routing/api/request/preference/RoutingPreferences.java index b728b99f8e3..3230bbf5968 100644 --- a/src/main/java/org/opentripplanner/routing/api/request/preference/RoutingPreferences.java +++ b/src/main/java/org/opentripplanner/routing/api/request/preference/RoutingPreferences.java @@ -7,6 +7,7 @@ import java.util.Objects; import java.util.function.Consumer; import javax.annotation.Nonnull; +import org.opentripplanner.routing.api.request.StreetMode; import org.opentripplanner.street.search.TraverseMode; /** User/trip cost/time/slack/reluctance search config. */ @@ -22,7 +23,6 @@ public final class RoutingPreferences implements Serializable { private final WheelchairPreferences wheelchair; private final BikePreferences bike; private final CarPreferences car; - private final VehicleRentalPreferences rental; private final SystemPreferences system; private final ItineraryFilterPreferences itineraryFilter; @@ -34,7 +34,6 @@ public RoutingPreferences() { this.wheelchair = WheelchairPreferences.DEFAULT; this.bike = BikePreferences.DEFAULT; this.car = CarPreferences.DEFAULT; - this.rental = VehicleRentalPreferences.DEFAULT; this.system = SystemPreferences.DEFAULT; this.itineraryFilter = ItineraryFilterPreferences.DEFAULT; } @@ -47,7 +46,6 @@ private RoutingPreferences(Builder builder) { this.street = requireNonNull(builder.street()); this.bike = requireNonNull(builder.bike()); this.car = requireNonNull(builder.car()); - this.rental = requireNonNull(builder.rental()); this.system = requireNonNull(builder.system()); this.itineraryFilter = requireNonNull(builder.itineraryFilter()); } @@ -92,10 +90,6 @@ public CarPreferences car() { return car; } - public VehicleRentalPreferences rental() { - return rental; - } - /** * Get parking preferences for the traverse mode. Note, only car and bike are supported. */ @@ -103,6 +97,24 @@ public VehicleParkingPreferences parking(TraverseMode mode) { return mode == TraverseMode.CAR ? car.parking() : bike.parking(); } + /** + * Get rental preferences for the traverse mode. Note, only car, scooter and bike are supported. + * + * TODO make scooter preferences independent of bike + */ + public VehicleRentalPreferences rental(TraverseMode mode) { + return mode == TraverseMode.CAR ? car.rental() : bike.rental(); + } + + /** + * Get rental preferences for the traverse mode. Note, only car, scooter and bike are supported. + * + * TODO make scooter preferences independent of bike + */ + public VehicleRentalPreferences rental(StreetMode mode) { + return mode == StreetMode.CAR_RENTAL ? car.rental() : bike.rental(); + } + @Nonnull public ItineraryFilterPreferences itineraryFilter() { return itineraryFilter; @@ -137,7 +149,6 @@ public boolean equals(Object o) { Objects.equals(wheelchair, that.wheelchair) && Objects.equals(bike, that.bike) && Objects.equals(car, that.car) && - Objects.equals(rental, that.rental) && Objects.equals(system, that.system) && Objects.equals(itineraryFilter, that.itineraryFilter) ); @@ -153,7 +164,6 @@ public int hashCode() { wheelchair, bike, car, - rental, system, itineraryFilter ); @@ -169,7 +179,6 @@ public static class Builder { private WheelchairPreferences wheelchair = null; private BikePreferences bike = null; private CarPreferences car = null; - private VehicleRentalPreferences rental = null; private SystemPreferences system = null; private ItineraryFilterPreferences itineraryFilter = null; @@ -250,15 +259,6 @@ public Builder withCar(Consumer body) { return this; } - public VehicleRentalPreferences rental() { - return rental == null ? original.rental : rental; - } - - public Builder withRental(Consumer body) { - this.rental = ifNotNull(this.rental, original.rental).copyOf().apply(body).build(); - return this; - } - public SystemPreferences system() { return system == null ? original.system : system; } diff --git a/src/main/java/org/opentripplanner/routing/api/request/preference/TransitPreferences.java b/src/main/java/org/opentripplanner/routing/api/request/preference/TransitPreferences.java index da5c4aad60d..1ad6e8ddacd 100644 --- a/src/main/java/org/opentripplanner/routing/api/request/preference/TransitPreferences.java +++ b/src/main/java/org/opentripplanner/routing/api/request/preference/TransitPreferences.java @@ -174,7 +174,7 @@ public boolean equals(Object o) { boardSlack.equals(that.boardSlack) && alightSlack.equals(that.alightSlack) && reluctanceForMode.equals(that.reluctanceForMode) && - otherThanPreferredRoutesPenalty == that.otherThanPreferredRoutesPenalty && + Objects.equals(otherThanPreferredRoutesPenalty, that.otherThanPreferredRoutesPenalty) && unpreferredCost.equals(that.unpreferredCost) && Objects.equals(relaxTransitPriorityGroup, that.relaxTransitPriorityGroup) && ignoreRealtimeUpdates == that.ignoreRealtimeUpdates && diff --git a/src/main/java/org/opentripplanner/routing/api/request/preference/VehicleRentalPreferences.java b/src/main/java/org/opentripplanner/routing/api/request/preference/VehicleRentalPreferences.java index 85740177659..8e18d2a81d5 100644 --- a/src/main/java/org/opentripplanner/routing/api/request/preference/VehicleRentalPreferences.java +++ b/src/main/java/org/opentripplanner/routing/api/request/preference/VehicleRentalPreferences.java @@ -2,12 +2,12 @@ import java.io.Serializable; import java.util.Objects; +import java.util.Set; import java.util.function.Consumer; import org.opentripplanner.framework.lang.DoubleUtils; import org.opentripplanner.framework.model.Cost; import org.opentripplanner.framework.model.Units; import org.opentripplanner.framework.tostring.ToStringBuilder; -import org.opentripplanner.routing.api.request.request.VehicleRentalRequest; /** * Preferences for renting a Bike, Car or other type of vehicle. @@ -24,6 +24,10 @@ public final class VehicleRentalPreferences implements Serializable { private final boolean useAvailabilityInformation; private final double arrivingInRentalVehicleAtDestinationCost; + private final boolean allowArrivingInRentedVehicleAtDestination; + + private final Set allowedNetworks; + private final Set bannedNetworks; private VehicleRentalPreferences() { this.pickupTime = 60; @@ -32,6 +36,9 @@ private VehicleRentalPreferences() { this.dropoffCost = Cost.costOfSeconds(30); this.useAvailabilityInformation = false; this.arrivingInRentalVehicleAtDestinationCost = 0; + this.allowArrivingInRentedVehicleAtDestination = false; + this.allowedNetworks = Set.of(); + this.bannedNetworks = Set.of(); } private VehicleRentalPreferences(Builder builder) { @@ -42,6 +49,10 @@ private VehicleRentalPreferences(Builder builder) { this.useAvailabilityInformation = builder.useAvailabilityInformation; this.arrivingInRentalVehicleAtDestinationCost = DoubleUtils.roundTo1Decimal(builder.arrivingInRentalVehicleAtDestinationCost); + this.allowArrivingInRentedVehicleAtDestination = + builder.allowArrivingInRentedVehicleAtDestination; + this.allowedNetworks = builder.allowedNetworks; + this.bannedNetworks = builder.bannedNetworks; } public static Builder of() { @@ -78,8 +89,6 @@ public int dropoffCost() { /** * Whether or not vehicle rental availability information will be used to plan vehicle rental * trips - * - * TODO: This belong in the request? */ public boolean useAvailabilityInformation() { return useAvailabilityInformation; @@ -87,13 +96,31 @@ public boolean useAvailabilityInformation() { /** * The cost of arriving at the destination with the rented vehicle, to discourage doing so. - * - * @see VehicleRentalRequest#allowArrivingInRentedVehicleAtDestination() */ public double arrivingInRentalVehicleAtDestinationCost() { return arrivingInRentalVehicleAtDestinationCost; } + /** + * Whether arriving at the destination with a rented (station) vehicle is allowed without dropping + * it off. + * + * @see VehicleRentalPreferences#arrivingInRentalVehicleAtDestinationCost() + */ + public boolean allowArrivingInRentedVehicleAtDestination() { + return allowArrivingInRentedVehicleAtDestination; + } + + /** The vehicle rental networks which may be used. If empty all networks may be used. */ + public Set allowedNetworks() { + return allowedNetworks; + } + + /** The vehicle rental networks which may not be used. If empty, no networks are banned. */ + public Set bannedNetworks() { + return bannedNetworks; + } + @Override public boolean equals(Object o) { if (this == o) return true; @@ -101,15 +128,18 @@ public boolean equals(Object o) { VehicleRentalPreferences that = (VehicleRentalPreferences) o; return ( pickupTime == that.pickupTime && - pickupCost == that.pickupCost && + Objects.equals(pickupCost, that.pickupCost) && dropoffTime == that.dropoffTime && - dropoffCost == that.dropoffCost && + Objects.equals(dropoffCost, that.dropoffCost) && useAvailabilityInformation == that.useAvailabilityInformation && Double.compare( that.arrivingInRentalVehicleAtDestinationCost, arrivingInRentalVehicleAtDestinationCost ) == - 0 + 0 && + allowArrivingInRentedVehicleAtDestination == that.allowArrivingInRentedVehicleAtDestination && + allowedNetworks.equals(that.allowedNetworks) && + bannedNetworks.equals(that.bannedNetworks) ); } @@ -121,7 +151,10 @@ public int hashCode() { dropoffTime, dropoffCost, useAvailabilityInformation, - arrivingInRentalVehicleAtDestinationCost + arrivingInRentalVehicleAtDestinationCost, + allowArrivingInRentedVehicleAtDestination, + allowedNetworks, + bannedNetworks ); } @@ -139,6 +172,12 @@ public String toString() { arrivingInRentalVehicleAtDestinationCost, DEFAULT.arrivingInRentalVehicleAtDestinationCost ) + .addBoolIfTrue( + "allowArrivingInRentedVehicleAtDestination", + allowArrivingInRentedVehicleAtDestination + ) + .addCol("allowedNetworks", allowedNetworks, DEFAULT.allowedNetworks) + .addCol("bannedNetworks", bannedNetworks, DEFAULT.bannedNetworks) .toString(); } @@ -151,6 +190,9 @@ public static class Builder { private Cost dropoffCost; private boolean useAvailabilityInformation; private double arrivingInRentalVehicleAtDestinationCost; + private boolean allowArrivingInRentedVehicleAtDestination; + private Set allowedNetworks; + private Set bannedNetworks; private Builder(VehicleRentalPreferences original) { this.original = original; @@ -161,6 +203,10 @@ private Builder(VehicleRentalPreferences original) { this.useAvailabilityInformation = original.useAvailabilityInformation; this.arrivingInRentalVehicleAtDestinationCost = original.arrivingInRentalVehicleAtDestinationCost; + this.allowArrivingInRentedVehicleAtDestination = + original.allowArrivingInRentedVehicleAtDestination; + this.allowedNetworks = original.allowedNetworks; + this.bannedNetworks = original.bannedNetworks; } public VehicleRentalPreferences original() { @@ -199,6 +245,23 @@ public Builder withArrivingInRentalVehicleAtDestinationCost( return this; } + public Builder withAllowArrivingInRentedVehicleAtDestination( + boolean allowArrivingInRentedVehicleAtDestination + ) { + this.allowArrivingInRentedVehicleAtDestination = allowArrivingInRentedVehicleAtDestination; + return this; + } + + public Builder withAllowedNetworks(Set allowedNetworks) { + this.allowedNetworks = allowedNetworks; + return this; + } + + public Builder withBannedNetworks(Set bannedNetworks) { + this.bannedNetworks = bannedNetworks; + return this; + } + public Builder apply(Consumer body) { body.accept(this); return this; diff --git a/src/main/java/org/opentripplanner/routing/api/request/request/JourneyRequest.java b/src/main/java/org/opentripplanner/routing/api/request/request/JourneyRequest.java index 39a775bf7f5..50e802690b3 100644 --- a/src/main/java/org/opentripplanner/routing/api/request/request/JourneyRequest.java +++ b/src/main/java/org/opentripplanner/routing/api/request/request/JourneyRequest.java @@ -6,18 +6,12 @@ // TODO VIA: Javadoc public class JourneyRequest implements Cloneable, Serializable { - // TODO VIA (Hannes): Move the fields below into StreetRequest - private VehicleRentalRequest rental = new VehicleRentalRequest(); private TransitRequest transit = new TransitRequest(); private StreetRequest access = new StreetRequest(); private StreetRequest egress = new StreetRequest(); private StreetRequest transfer = new StreetRequest(); private StreetRequest direct = new StreetRequest(); - public VehicleRentalRequest rental() { - return rental; - } - public TransitRequest transit() { return transit; } @@ -58,7 +52,6 @@ public RequestModes modes() { public JourneyRequest clone() { try { var clone = (JourneyRequest) super.clone(); - clone.rental = this.rental.clone(); clone.transit = this.transit.clone(); clone.access = this.access.clone(); clone.egress = this.egress.clone(); diff --git a/src/main/java/org/opentripplanner/routing/api/request/request/StreetRequest.java b/src/main/java/org/opentripplanner/routing/api/request/request/StreetRequest.java index 587efda6e05..42928a0a70a 100644 --- a/src/main/java/org/opentripplanner/routing/api/request/request/StreetRequest.java +++ b/src/main/java/org/opentripplanner/routing/api/request/request/StreetRequest.java @@ -4,7 +4,6 @@ import org.opentripplanner.routing.api.request.StreetMode; // TODO VIA: Javadoc -// TODO VIA (Hannes): Missing VehicleRentalRequest and VehicleParkingRequest public class StreetRequest implements Cloneable, Serializable { private StreetMode mode; diff --git a/src/main/java/org/opentripplanner/routing/api/request/request/VehicleRentalRequest.java b/src/main/java/org/opentripplanner/routing/api/request/request/VehicleRentalRequest.java deleted file mode 100644 index 90e39b22ff7..00000000000 --- a/src/main/java/org/opentripplanner/routing/api/request/request/VehicleRentalRequest.java +++ /dev/null @@ -1,66 +0,0 @@ -package org.opentripplanner.routing.api.request.request; - -import java.io.Serializable; -import java.util.HashSet; -import java.util.Set; -import org.opentripplanner.routing.api.request.preference.VehicleRentalPreferences; -import org.opentripplanner.service.vehiclerental.model.VehicleRentalStation; - -// TODO VIA: Javadoc -public class VehicleRentalRequest implements Cloneable, Serializable { - - private Set allowedNetworks = Set.of(); - private Set bannedNetworks = Set.of(); - - private boolean allowArrivingInRentedVehicleAtDestination = false; - - // TODO VIA (Hannes): Move useAvailabilityInformation here - - public void setAllowedNetworks(Set allowedNetworks) { - this.allowedNetworks = allowedNetworks; - } - - /** The vehicle rental networks which may be used. If empty all networks may be used. */ - public Set allowedNetworks() { - return allowedNetworks; - } - - public void setBannedNetworks(Set bannedNetworks) { - this.bannedNetworks = bannedNetworks; - } - - /** The vehicle rental networks which may not be used. If empty, no networks are banned. */ - public Set bannedNetworks() { - return bannedNetworks; - } - - public void setAllowArrivingInRentedVehicleAtDestination( - boolean allowArrivingInRentedVehicleAtDestination - ) { - this.allowArrivingInRentedVehicleAtDestination = allowArrivingInRentedVehicleAtDestination; - } - - /** - * Whether arriving at the destination with a rented (station) bicycle is allowed without dropping - * it off. - * - * @see VehicleRentalPreferences#arrivingInRentalVehicleAtDestinationCost() - * @see VehicleRentalStation#isArrivingInRentalVehicleAtDestinationAllowed - */ - public boolean allowArrivingInRentedVehicleAtDestination() { - return allowArrivingInRentedVehicleAtDestination; - } - - public VehicleRentalRequest clone() { - try { - var clone = (VehicleRentalRequest) super.clone(); - clone.allowedNetworks = new HashSet<>(this.allowedNetworks); - clone.bannedNetworks = new HashSet<>(this.bannedNetworks); - - return clone; - } catch (CloneNotSupportedException e) { - /* this will never happen since our super is the cloneable object */ - throw new RuntimeException(e); - } - } -} diff --git a/src/main/java/org/opentripplanner/routing/error/PathNotFoundException.java b/src/main/java/org/opentripplanner/routing/error/PathNotFoundException.java index 18d94d23038..a4071f9911e 100644 --- a/src/main/java/org/opentripplanner/routing/error/PathNotFoundException.java +++ b/src/main/java/org/opentripplanner/routing/error/PathNotFoundException.java @@ -4,6 +4,5 @@ * Indicates that the call to org.opentripplanner.routing.services.PathService returned either null * or ZERO paths. * - * @see org.opentripplanner.api.resource.PlannerResource for where this is (locally) thrown. */ public class PathNotFoundException extends RuntimeException {} diff --git a/src/main/java/org/opentripplanner/routing/service/DefaultRoutingService.java b/src/main/java/org/opentripplanner/routing/service/DefaultRoutingService.java index 320ffb2117d..9879b52c9c1 100644 --- a/src/main/java/org/opentripplanner/routing/service/DefaultRoutingService.java +++ b/src/main/java/org/opentripplanner/routing/service/DefaultRoutingService.java @@ -58,6 +58,12 @@ public ViaRoutingResponse route(RouteViaRequest request) { } private void logResponse(RoutingResponse response) { + if (response.getTripPlan().itineraries.isEmpty() && response.getRoutingErrors().isEmpty()) { + // We should provide an error if there is no results, this is important for the client so + // it knows if it can page or abort. + LOG.warn("The routing result is empty, but there is no errors..."); + } + if (LOG.isDebugEnabled()) { var m = response.getMetadata(); var text = MultiLineToStringBuilder diff --git a/src/main/java/org/opentripplanner/service/vehiclerental/model/VehicleRentalPlace.java b/src/main/java/org/opentripplanner/service/vehiclerental/model/VehicleRentalPlace.java index ee181f7b3c1..1725e7df2dd 100644 --- a/src/main/java/org/opentripplanner/service/vehiclerental/model/VehicleRentalPlace.java +++ b/src/main/java/org/opentripplanner/service/vehiclerental/model/VehicleRentalPlace.java @@ -2,7 +2,7 @@ import java.util.Set; import org.opentripplanner.framework.i18n.I18NString; -import org.opentripplanner.routing.api.request.request.VehicleRentalRequest; +import org.opentripplanner.routing.api.request.preference.VehicleRentalPreferences; import org.opentripplanner.street.model.RentalFormFactor; import org.opentripplanner.transit.model.framework.FeedScopedId; @@ -80,22 +80,22 @@ public interface VehicleRentalPlace { /** Deep links for this rental station or individual vehicle */ VehicleRentalStationUris getRentalUris(); - default boolean networkIsNotAllowed(VehicleRentalRequest request) { + default boolean networkIsNotAllowed(VehicleRentalPreferences preferences) { if ( getNetwork() == null && - (!request.allowedNetworks().isEmpty() || !request.bannedNetworks().isEmpty()) + (!preferences.allowedNetworks().isEmpty() || !preferences.bannedNetworks().isEmpty()) ) { return false; } - if (request.bannedNetworks().contains(getNetwork())) { + if (preferences.bannedNetworks().contains(getNetwork())) { return true; } - if (request.allowedNetworks().isEmpty()) { + if (preferences.allowedNetworks().isEmpty()) { return false; } - return !request.allowedNetworks().contains(getNetwork()); + return !preferences.allowedNetworks().contains(getNetwork()); } } diff --git a/src/main/java/org/opentripplanner/service/vehiclerental/street/StreetVehicleRentalLink.java b/src/main/java/org/opentripplanner/service/vehiclerental/street/StreetVehicleRentalLink.java index 96bbdaf4c0d..4a18aae03c2 100644 --- a/src/main/java/org/opentripplanner/service/vehiclerental/street/StreetVehicleRentalLink.java +++ b/src/main/java/org/opentripplanner/service/vehiclerental/street/StreetVehicleRentalLink.java @@ -52,7 +52,8 @@ public State[] traverse(State s0) { return State.empty(); } - if (vehicleRentalPlaceVertex.getStation().networkIsNotAllowed(s0.getRequest().rental())) { + var preferences = s0.getPreferences().rental(s0.getRequest().mode()); + if (vehicleRentalPlaceVertex.getStation().networkIsNotAllowed(preferences)) { return State.empty(); } diff --git a/src/main/java/org/opentripplanner/service/vehiclerental/street/VehicleRentalEdge.java b/src/main/java/org/opentripplanner/service/vehiclerental/street/VehicleRentalEdge.java index 9ec6cf79003..66665f73b54 100644 --- a/src/main/java/org/opentripplanner/service/vehiclerental/street/VehicleRentalEdge.java +++ b/src/main/java/org/opentripplanner/service/vehiclerental/street/VehicleRentalEdge.java @@ -49,10 +49,10 @@ public State[] traverse(State s0) { VehicleRentalPlaceVertex stationVertex = (VehicleRentalPlaceVertex) tov; VehicleRentalPlace station = stationVertex.getStation(); String network = station.getNetwork(); - var preferences = s0.getPreferences(); - boolean realtimeAvailability = preferences.rental().useAvailabilityInformation(); + var preferences = s0.getPreferences().rental(formFactor.traverseMode); + boolean realtimeAvailability = preferences.useAvailabilityInformation(); - if (station.networkIsNotAllowed(s0.getRequest().rental())) { + if (station.networkIsNotAllowed(preferences)) { return State.empty(); } @@ -128,7 +128,7 @@ public State[] traverse(State s0) { s1.beginFloatingVehicleRenting(formFactor, network, false); } else { boolean mayKeep = - s0.getRequest().rental().allowArrivingInRentedVehicleAtDestination() && + preferences.allowArrivingInRentedVehicleAtDestination() && station.isArrivingInRentalVehicleAtDestinationAllowed(); s1.beginVehicleRentingAtStation(formFactor, network, mayKeep, false); } @@ -161,12 +161,8 @@ public State[] traverse(State s0) { } } - s1.incrementWeight( - pickedUp ? preferences.rental().pickupCost() : preferences.rental().dropoffCost() - ); - s1.incrementTimeInSeconds( - pickedUp ? preferences.rental().pickupTime() : preferences.rental().dropoffTime() - ); + s1.incrementWeight(pickedUp ? preferences.pickupCost() : preferences.dropoffCost()); + s1.incrementTimeInSeconds(pickedUp ? preferences.pickupTime() : preferences.dropoffTime()); s1.setBackMode(null); return s1.makeStateArray(); } diff --git a/src/main/java/org/opentripplanner/standalone/config/routerequest/RouteRequestConfig.java b/src/main/java/org/opentripplanner/standalone/config/routerequest/RouteRequestConfig.java index f6a79ea9192..e600f1f8f12 100644 --- a/src/main/java/org/opentripplanner/standalone/config/routerequest/RouteRequestConfig.java +++ b/src/main/java/org/opentripplanner/standalone/config/routerequest/RouteRequestConfig.java @@ -170,22 +170,17 @@ cost function. The cost function (`unpreferredCost`) is defined as a linear func TransitPriorityGroupConfig.mapTransitRequest(c, request.journey().transit()); // Map preferences - request.withPreferences(preferences -> mapPreferences(c, request, preferences)); + request.withPreferences(preferences -> mapPreferences(c, preferences)); return request; } - private static void mapPreferences( - NodeAdapter c, - RouteRequest request, - RoutingPreferences.Builder preferences - ) { + private static void mapPreferences(NodeAdapter c, RoutingPreferences.Builder preferences) { preferences.withTransit(it -> mapTransitPreferences(c, it)); preferences.withBike(it -> mapBikePreferences(c, it)); preferences.withStreet(it -> mapStreetPreferences(c, it)); preferences.withCar(it -> mapCarPreferences(c, it)); preferences.withSystem(it -> mapSystemPreferences(c, it)); - preferences.withRental(it -> setVehicleRental(c, request, it)); preferences.withTransfer(it -> mapTransferPreferences(c, it)); preferences.withWalk(it -> mapWalkPreferences(c, it)); preferences.withWheelchair(it -> mapWheelchairPreferences(c, it, WHEELCHAIR_ACCESSIBILITY)); @@ -508,7 +503,8 @@ Vehicle parking tags can originate from different places depending on the origin ) .asStringSet(List.of()) ) - ); + ) + .withRental(it -> setVehicleRental(c, it)); } private static void mapStreetPreferences(NodeAdapter c, StreetPreferences.Builder builder) { @@ -821,7 +817,8 @@ Vehicle parking tags can originate from different places depending on the origin ) .asStringSet(List.of()) ) - ); + ) + .withRental(it -> setVehicleRental(c, it)); } private static void mapSystemPreferences(NodeAdapter c, SystemPreferences.Builder builder) { diff --git a/src/main/java/org/opentripplanner/standalone/config/routerequest/VehicleRentalConfig.java b/src/main/java/org/opentripplanner/standalone/config/routerequest/VehicleRentalConfig.java index 94f392cc313..057daa7001c 100644 --- a/src/main/java/org/opentripplanner/standalone/config/routerequest/VehicleRentalConfig.java +++ b/src/main/java/org/opentripplanner/standalone/config/routerequest/VehicleRentalConfig.java @@ -5,10 +5,7 @@ import static org.opentripplanner.standalone.config.framework.json.OtpVersion.V2_2; import static org.opentripplanner.standalone.config.framework.json.OtpVersion.V2_3; -import org.opentripplanner.routing.api.request.RouteRequest; -import org.opentripplanner.routing.api.request.preference.RoutingPreferences; import org.opentripplanner.routing.api.request.preference.VehicleRentalPreferences; -import org.opentripplanner.routing.api.request.request.VehicleRentalRequest; import org.opentripplanner.standalone.config.framework.json.NodeAdapter; public class VehicleRentalConfig { @@ -53,56 +50,42 @@ static void mapRentalPreferences(NodeAdapter c, VehicleRentalPreferences.Builder "The cost of arriving at the destination with the rented vehicle, to discourage doing so." ) .asDouble(dft.arrivingInRentalVehicleAtDestinationCost()) - ); - } - - static void setVehicleRentalRequestOptions(NodeAdapter c, RouteRequest request) { - VehicleRentalRequest vehicleRentalRequest = request.journey().rental(); - - vehicleRentalRequest.setAllowedNetworks( - c - .of("allowedNetworks") - .since(V2_1) - .summary( - "The vehicle rental networks which may be used. If empty all networks may be used." - ) - .asStringSet(vehicleRentalRequest.allowedNetworks()) - ); - vehicleRentalRequest.setBannedNetworks( - c - .of("bannedNetworks") - .since(V2_1) - .summary( - "The vehicle rental networks which may not be used. If empty, no networks are banned." - ) - .asStringSet(vehicleRentalRequest.bannedNetworks()) - ); - - request - .journey() - .rental() - .setAllowArrivingInRentedVehicleAtDestination( + ) + .withAllowArrivingInRentedVehicleAtDestination( c .of("allowKeepingAtDestination") .since(V2_2) .summary( "If a vehicle should be allowed to be kept at the end of a station-based rental." ) - .asBoolean(request.journey().rental().allowArrivingInRentedVehicleAtDestination()) + .asBoolean(dft.allowArrivingInRentedVehicleAtDestination()) + ) + .withAllowedNetworks( + c + .of("allowedNetworks") + .since(V2_1) + .summary( + "The vehicle rental networks which may be used. If empty all networks may be used." + ) + .asStringSet(dft.allowedNetworks()) + ) + .withBannedNetworks( + c + .of("bannedNetworks") + .since(V2_1) + .summary( + "The vehicle rental networks which may not be used. If empty, no networks are banned." + ) + .asStringSet(dft.bannedNetworks()) ); } - static void setVehicleRental( - NodeAdapter c, - RouteRequest request, - VehicleRentalPreferences.Builder preferences - ) { + static void setVehicleRental(NodeAdapter c, VehicleRentalPreferences.Builder preferences) { var vehicleRental = c .of("vehicleRental") .since(V2_3) .summary("Vehicle rental options") .asObject(); mapRentalPreferences(vehicleRental, preferences); - setVehicleRentalRequestOptions(vehicleRental, request); } } diff --git a/src/main/java/org/opentripplanner/standalone/server/OTPWebApplication.java b/src/main/java/org/opentripplanner/standalone/server/OTPWebApplication.java index 56aaa2d1361..b238a74c7d3 100644 --- a/src/main/java/org/opentripplanner/standalone/server/OTPWebApplication.java +++ b/src/main/java/org/opentripplanner/standalone/server/OTPWebApplication.java @@ -7,7 +7,6 @@ import io.micrometer.prometheus.PrometheusMeterRegistry; import jakarta.ws.rs.container.ContainerResponseFilter; import jakarta.ws.rs.core.Application; -import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; @@ -17,10 +16,9 @@ import org.glassfish.jersey.internal.inject.AbstractBinder; import org.glassfish.jersey.internal.inject.Binder; import org.glassfish.jersey.jackson.internal.jackson.jaxrs.json.JacksonJsonProvider; -import org.glassfish.jersey.server.ServerProperties; import org.opentripplanner.api.common.OTPExceptionMapper; -import org.opentripplanner.api.configuration.APIEndpoints; -import org.opentripplanner.api.json.JSONObjectMapperProvider; +import org.opentripplanner.apis.APIEndpoints; +import org.opentripplanner.ext.restapi.serialization.JSONObjectMapperProvider; import org.opentripplanner.framework.application.OTPFeature; import org.opentripplanner.standalone.api.OtpServerRequestContext; import org.slf4j.bridge.SLF4JBridgeHandler; diff --git a/src/main/java/org/opentripplanner/street/model/edge/StreetTransitEntityLink.java b/src/main/java/org/opentripplanner/street/model/edge/StreetTransitEntityLink.java index 4fe66735532..926eebc31d9 100644 --- a/src/main/java/org/opentripplanner/street/model/edge/StreetTransitEntityLink.java +++ b/src/main/java/org/opentripplanner/street/model/edge/StreetTransitEntityLink.java @@ -98,7 +98,11 @@ else if ( s0.isRentingVehicleFromStation() && !( s0.mayKeepRentedVehicleAtDestination() && - s0.getRequest().rental().allowArrivingInRentedVehicleAtDestination() + s0 + .getRequest() + .preferences() + .rental(s0.getRequest().mode()) + .allowArrivingInRentedVehicleAtDestination() ) ) { yield State.empty(); @@ -133,12 +137,13 @@ else if ( @Nonnull private State[] buildState(State s0, StateEditor s1, RoutingPreferences pref) { + var rentalPreferences = s0.getRequest().preferences().rental(s0.getRequest().mode()); if ( s0.isRentingVehicleFromStation() && s0.mayKeepRentedVehicleAtDestination() && - s0.getRequest().rental().allowArrivingInRentedVehicleAtDestination() + rentalPreferences.allowArrivingInRentedVehicleAtDestination() ) { - s1.incrementWeight(pref.rental().arrivingInRentalVehicleAtDestinationCost()); + s1.incrementWeight(rentalPreferences.arrivingInRentalVehicleAtDestinationCost()); } s1.setBackMode(null); diff --git a/src/main/java/org/opentripplanner/street/model/edge/TemporaryFreeEdge.java b/src/main/java/org/opentripplanner/street/model/edge/TemporaryFreeEdge.java index 35045db848a..011d0fec7f1 100644 --- a/src/main/java/org/opentripplanner/street/model/edge/TemporaryFreeEdge.java +++ b/src/main/java/org/opentripplanner/street/model/edge/TemporaryFreeEdge.java @@ -42,12 +42,13 @@ public State[] traverse(State s0) { s1.incrementWeight(1); s1.setBackMode(null); + var rentalPreferences = s0.getPreferences().rental(s0.getRequest().mode()); if ( s0.isRentingVehicleFromStation() && s0.mayKeepRentedVehicleAtDestination() && - s0.getRequest().rental().allowArrivingInRentedVehicleAtDestination() + rentalPreferences.allowArrivingInRentedVehicleAtDestination() ) { - s1.incrementWeight(s0.getPreferences().rental().arrivingInRentalVehicleAtDestinationCost()); + s1.incrementWeight(rentalPreferences.arrivingInRentalVehicleAtDestinationCost()); } return s1.makeStateArray(); diff --git a/src/main/java/org/opentripplanner/street/search/StreetSearchBuilder.java b/src/main/java/org/opentripplanner/street/search/StreetSearchBuilder.java index b4ac98674d0..079cd29706f 100644 --- a/src/main/java/org/opentripplanner/street/search/StreetSearchBuilder.java +++ b/src/main/java/org/opentripplanner/street/search/StreetSearchBuilder.java @@ -102,7 +102,7 @@ protected void prepareInitialStates(Collection initialStates) { @Override protected void initializeHeuristic( RemainingWeightHeuristic heuristic, - Set origin, + Set ignored, Set destination, boolean arriveBy ) { @@ -111,7 +111,6 @@ protected void initializeHeuristic( } else if (heuristic instanceof EuclideanRemainingWeightHeuristic euclideanHeuristic) { euclideanHeuristic.initialize( streetRequest.mode(), - origin, destination, arriveBy, routeRequest.preferences() diff --git a/src/main/java/org/opentripplanner/street/search/request/StreetSearchRequest.java b/src/main/java/org/opentripplanner/street/search/request/StreetSearchRequest.java index 6d8bd5783f3..c33ed6a35e9 100644 --- a/src/main/java/org/opentripplanner/street/search/request/StreetSearchRequest.java +++ b/src/main/java/org/opentripplanner/street/search/request/StreetSearchRequest.java @@ -12,7 +12,6 @@ import org.opentripplanner.routing.api.request.RouteRequest; import org.opentripplanner.routing.api.request.StreetMode; import org.opentripplanner.routing.api.request.preference.RoutingPreferences; -import org.opentripplanner.routing.api.request.request.VehicleRentalRequest; import org.opentripplanner.street.model.vertex.Vertex; import org.opentripplanner.street.search.intersection_model.IntersectionTraversalCalculator; import org.opentripplanner.street.search.state.State; @@ -39,7 +38,6 @@ public class StreetSearchRequest implements AStarRequest { private final StreetMode mode; private final boolean arriveBy; private final boolean wheelchair; - private final VehicleRentalRequest rental; private final GenericLocation from; private final Envelope fromEnvelope; @@ -60,7 +58,6 @@ private StreetSearchRequest() { this.mode = StreetMode.WALK; this.arriveBy = false; this.wheelchair = false; - this.rental = new VehicleRentalRequest(); this.from = null; this.fromEnvelope = null; this.to = null; @@ -73,7 +70,6 @@ private StreetSearchRequest() { this.mode = builder.mode; this.arriveBy = builder.arriveBy; this.wheelchair = builder.wheelchair; - this.rental = builder.rental; this.from = builder.from; this.fromEnvelope = createEnvelope(from); this.to = builder.to; @@ -115,10 +111,6 @@ public boolean wheelchair() { return wheelchair; } - public VehicleRentalRequest rental() { - return rental; - } - public GenericLocation from() { return from; } diff --git a/src/main/java/org/opentripplanner/street/search/request/StreetSearchRequestBuilder.java b/src/main/java/org/opentripplanner/street/search/request/StreetSearchRequestBuilder.java index 439e65a3289..fd2eff30e7e 100644 --- a/src/main/java/org/opentripplanner/street/search/request/StreetSearchRequestBuilder.java +++ b/src/main/java/org/opentripplanner/street/search/request/StreetSearchRequestBuilder.java @@ -5,7 +5,6 @@ import org.opentripplanner.model.GenericLocation; import org.opentripplanner.routing.api.request.StreetMode; import org.opentripplanner.routing.api.request.preference.RoutingPreferences; -import org.opentripplanner.routing.api.request.request.VehicleRentalRequest; public class StreetSearchRequestBuilder { @@ -14,7 +13,6 @@ public class StreetSearchRequestBuilder { RoutingPreferences preferences; boolean arriveBy; boolean wheelchair; - VehicleRentalRequest rental; GenericLocation from; GenericLocation to; @@ -24,7 +22,6 @@ public class StreetSearchRequestBuilder { this.preferences = original.preferences(); this.arriveBy = original.arriveBy(); this.wheelchair = original.wheelchair(); - this.rental = original.rental(); this.from = original.from(); this.to = original.to(); } @@ -58,11 +55,6 @@ public StreetSearchRequestBuilder withWheelchair(boolean wheelchair) { return this; } - public StreetSearchRequestBuilder withRental(VehicleRentalRequest rental) { - this.rental = rental; - return this; - } - public StreetSearchRequestBuilder withFrom(GenericLocation from) { this.from = from; return this; diff --git a/src/main/java/org/opentripplanner/street/search/request/StreetSearchRequestMapper.java b/src/main/java/org/opentripplanner/street/search/request/StreetSearchRequestMapper.java index 9f1f3c567f8..b4193e709e3 100644 --- a/src/main/java/org/opentripplanner/street/search/request/StreetSearchRequestMapper.java +++ b/src/main/java/org/opentripplanner/street/search/request/StreetSearchRequestMapper.java @@ -11,7 +11,6 @@ public static StreetSearchRequestBuilder map(RouteRequest opt) { .withStartTime(opt.dateTime()) .withPreferences(opt.preferences()) .withWheelchair(opt.wheelchair()) - .withRental(opt.journey().rental()) .withFrom(opt.from()) .withTo(opt.to()); } @@ -22,7 +21,6 @@ public static StreetSearchRequestBuilder mapToTransferRequest(RouteRequest opt) .withStartTime(Instant.ofEpochSecond(0)) .withPreferences(opt.preferences()) .withWheelchair(opt.wheelchair()) - .withRental(opt.journey().rental()) .withMode(opt.journey().transfer().mode()); } } diff --git a/src/main/java/org/opentripplanner/street/search/state/State.java b/src/main/java/org/opentripplanner/street/search/state/State.java index 37c3e81c097..deef516a674 100644 --- a/src/main/java/org/opentripplanner/street/search/state/State.java +++ b/src/main/java/org/opentripplanner/street/search/state/State.java @@ -214,7 +214,10 @@ private boolean vehicleRentalIsFinished() { !stateData.insideNoRentalDropOffArea ) || ( - getRequest().rental().allowArrivingInRentedVehicleAtDestination() && + getRequest() + .preferences() + .rental(getRequest().mode()) + .allowArrivingInRentedVehicleAtDestination() && stateData.mayKeepRentedVehicleAtDestination && stateData.vehicleRentalState == VehicleRentalState.RENTING_FROM_STATION ) @@ -503,7 +506,10 @@ private double getWalkDistanceDelta() { private State reversedClone() { StreetSearchRequest reversedRequest = request .copyOfReversed(getTime()) - .withPreferences(p -> p.withRental(r -> r.withUseAvailabilityInformation(false))) + .withPreferences(p -> { + p.withCar(c -> c.withRental(r -> r.withUseAvailabilityInformation(false))); + p.withBike(b -> b.withRental(r -> r.withUseAvailabilityInformation(false))); + }) .build(); StateData newStateData = stateData.clone(); newStateData.backMode = null; diff --git a/src/main/java/org/opentripplanner/street/search/state/StateData.java b/src/main/java/org/opentripplanner/street/search/state/StateData.java index 77d359248aa..cc2bfa5a57a 100644 --- a/src/main/java/org/opentripplanner/street/search/state/StateData.java +++ b/src/main/java/org/opentripplanner/street/search/state/StateData.java @@ -83,10 +83,11 @@ public static List getInitialStateDatas( StreetSearchRequest request, Function stateDataConstructor ) { + var rentalPreferences = request.preferences().rental(request.mode()); return getInitialStateDatas( request.mode(), request.arriveBy(), - request.rental().allowArrivingInRentedVehicleAtDestination(), + rentalPreferences.allowArrivingInRentedVehicleAtDestination(), stateDataConstructor ); } @@ -97,10 +98,11 @@ public static List getInitialStateDatas( * the given {@code request}. */ public static StateData getBaseCaseStateData(StreetSearchRequest request) { + var rentalPreferences = request.preferences().rental(request.mode()); var stateDatas = getInitialStateDatas( request.mode(), request.arriveBy(), - request.rental().allowArrivingInRentedVehicleAtDestination(), + rentalPreferences.allowArrivingInRentedVehicleAtDestination(), StateData::new ); diff --git a/src/main/java/org/opentripplanner/street/search/strategy/EuclideanRemainingWeightHeuristic.java b/src/main/java/org/opentripplanner/street/search/strategy/EuclideanRemainingWeightHeuristic.java index 36e4a57f8ec..e43278901d4 100644 --- a/src/main/java/org/opentripplanner/street/search/strategy/EuclideanRemainingWeightHeuristic.java +++ b/src/main/java/org/opentripplanner/street/search/strategy/EuclideanRemainingWeightHeuristic.java @@ -26,7 +26,6 @@ public class EuclideanRemainingWeightHeuristic implements RemainingWeightHeurist // not work correctly. public void initialize( StreetMode streetMode, - Set fromVertices, Set toVertices, boolean arriveBy, RoutingPreferences preferences diff --git a/src/main/java/org/opentripplanner/transit/model/timetable/ScheduledTripTimes.java b/src/main/java/org/opentripplanner/transit/model/timetable/ScheduledTripTimes.java index f502a220073..ff3f61394ae 100644 --- a/src/main/java/org/opentripplanner/transit/model/timetable/ScheduledTripTimes.java +++ b/src/main/java/org/opentripplanner/transit/model/timetable/ScheduledTripTimes.java @@ -11,9 +11,11 @@ import java.util.OptionalInt; import java.util.function.Supplier; import javax.annotation.Nullable; +import org.opentripplanner.framework.error.OtpError; import org.opentripplanner.framework.i18n.I18NString; import org.opentripplanner.framework.lang.IntUtils; import org.opentripplanner.framework.time.DurationUtils; +import org.opentripplanner.framework.time.TimeUtils; import org.opentripplanner.model.BookingInfo; import org.opentripplanner.transit.model.basic.Accessibility; import org.opentripplanner.transit.model.framework.DataValidationException; @@ -134,7 +136,7 @@ public int getServiceCode() { @Override public int getScheduledArrivalTime(final int stop) { - return arrivalTimes[stop] + timeShift; + return timeShifted(arrivalTimes[stop]); } @Override @@ -144,12 +146,12 @@ public int getArrivalTime(final int stop) { @Override public int getArrivalDelay(final int stop) { - return getArrivalTime(stop) - (arrivalTimes[stop] + timeShift); + return getArrivalTime(stop) - timeShifted(arrivalTimes[stop]); } @Override public int getScheduledDepartureTime(final int stop) { - return departureTimes[stop] + timeShift; + return timeShifted(departureTimes[stop]); } @Override @@ -159,7 +161,7 @@ public int getDepartureTime(final int stop) { @Override public int getDepartureDelay(final int stop) { - return getDepartureTime(stop) - (departureTimes[stop] + timeShift); + return getDepartureTime(stop) - timeShifted(departureTimes[stop]); } @Override @@ -314,9 +316,9 @@ I18NString[] copyHeadsigns(Supplier defaultValue) { /* private methods */ private void validate() { - int lastStop = departureTimes.length - 1; - IntUtils.requireInRange(departureTimes[0], MIN_TIME, MAX_TIME); - IntUtils.requireInRange(arrivalTimes[lastStop], MIN_TIME, MAX_TIME); + // Validate first departure time and last arrival time + validateTimeInRange("departureTime", departureTimes, 0); + validateTimeInRange("arrivalTime", arrivalTimes, arrivalTimes.length - 1); // TODO: This class is used by FLEX, so we can not validate increasing TripTimes // validateNonIncreasingTimes(); } @@ -356,4 +358,27 @@ private void validateNonIncreasingTimes() { prevDep = dep; } } + + private int timeShifted(int time) { + return timeShift + time; + } + + private void validateTimeInRange(String field, int[] times, int stopPos) { + int t = timeShifted(times[stopPos]); + + if (t < MIN_TIME || t > MAX_TIME) { + throw new DataValidationException( + OtpError.of( + "TripTimeOutOfRange", + "The %s is not in range[%s, %s]. Time: %s, stop-pos: %d, trip: %s.", + field, + DurationUtils.durationToStr(MIN_TIME), + DurationUtils.durationToStr(MAX_TIME), + TimeUtils.timeToStrLong(t), + stopPos, + trip.getId() + ) + ); + } + } } diff --git a/src/main/resources/org/opentripplanner/apis/transmodel/schema.graphql b/src/main/resources/org/opentripplanner/apis/transmodel/schema.graphql index 2eff7d94020..07067acdb28 100644 --- a/src/main/resources/org/opentripplanner/apis/transmodel/schema.graphql +++ b/src/main/resources/org/opentripplanner/apis/transmodel/schema.graphql @@ -549,6 +549,8 @@ type PtSituationElement { summary: [MultilingualString!]! "Period this situation is in effect" validityPeriod: ValidityPeriod + "Operator's version number for the situation element." + version: Int "Timestamp when the situation element was updated." versionedAtTime: DateTime } @@ -1286,6 +1288,8 @@ type TripPattern { expectedStartTime: DateTime! "Generalized cost or weight of the itinerary. Used for debugging." generalizedCost: Int + "A second cost or weight of the itinerary. Some use-cases like pass-through and transit-priority-groups use a second cost during routing. This is used for debugging." + generalizedCost2: Int "A list of legs. Each leg is either a walking (cycling, car) portion of the trip, or a ride leg on a particular vehicle. So a trip where the use walks to the Q train, transfers to the 6, then walks to their destination, has four legs." legs: [Leg!]! "Time that the trip departs." @@ -1644,7 +1648,7 @@ enum RoutingErrorCode { noStopsInRange "No transit connection was found between the origin and destination withing the operating day or the next day" noTransitConnection - "Transit connection was found, but it was outside the search window, see metadata for the next search window" + "A transit connection was found, but it was outside the search window. Use paging to navigate to a result." noTransitConnectionInSearchWindow "The coordinates are outside the bounds of the data currently loaded into the system" outsideBounds diff --git a/src/test/java/org/opentripplanner/astar/strategy/MaxCountSkipEdgeStrategyTest.java b/src/test/java/org/opentripplanner/astar/strategy/MaxCountSkipEdgeStrategyTest.java index 04844d65da2..17dc26a4c5e 100644 --- a/src/test/java/org/opentripplanner/astar/strategy/MaxCountSkipEdgeStrategyTest.java +++ b/src/test/java/org/opentripplanner/astar/strategy/MaxCountSkipEdgeStrategyTest.java @@ -12,7 +12,7 @@ class MaxCountSkipEdgeStrategyTest { @Test void countStops() { var state = TestStateBuilder.ofWalking().stop().build(); - var strategy = new MaxCountSkipEdgeStrategy<>(1, NearbyStopFinder::isTransitVertex); + var strategy = new MaxCountSkipEdgeStrategy<>(1, NearbyStopFinder::hasReachedStop); assertFalse(strategy.shouldSkipEdge(state, null)); assertTrue(strategy.shouldSkipEdge(state, null)); } @@ -20,9 +20,17 @@ void countStops() { @Test void doNotCountStop() { var state = TestStateBuilder.ofWalking().build(); - var strategy = new MaxCountSkipEdgeStrategy<>(1, NearbyStopFinder::isTransitVertex); + var strategy = new MaxCountSkipEdgeStrategy<>(1, NearbyStopFinder::hasReachedStop); assertFalse(strategy.shouldSkipEdge(state, null)); assertFalse(strategy.shouldSkipEdge(state, null)); assertFalse(strategy.shouldSkipEdge(state, null)); } + + @Test + void nonFinalState() { + var state = TestStateBuilder.ofScooterRentalArriveBy().stop().build(); + assertFalse(state.isFinal()); + var strategy = new MaxCountSkipEdgeStrategy<>(1, NearbyStopFinder::hasReachedStop); + assertFalse(strategy.shouldSkipEdge(state, null)); + } } diff --git a/src/test/java/org/opentripplanner/api/common/PlannerResourceTest.java b/src/test/java/org/opentripplanner/ext/restapi/resources/PlannerResourceTest.java similarity index 95% rename from src/test/java/org/opentripplanner/api/common/PlannerResourceTest.java rename to src/test/java/org/opentripplanner/ext/restapi/resources/PlannerResourceTest.java index 36e0650b081..a86e270a2af 100644 --- a/src/test/java/org/opentripplanner/api/common/PlannerResourceTest.java +++ b/src/test/java/org/opentripplanner/ext/restapi/resources/PlannerResourceTest.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.common; +package org.opentripplanner.ext.restapi.resources; import static graphql.Assert.assertNotNull; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -12,7 +12,6 @@ import org.opentripplanner.TestServerContext; import org.opentripplanner._support.time.ZoneIds; import org.opentripplanner.api.parameter.QualifiedModeSet; -import org.opentripplanner.api.resource.PlannerResource; import org.opentripplanner.routing.api.request.RequestModes; import org.opentripplanner.routing.graph.Graph; import org.opentripplanner.standalone.api.OtpServerRequestContext; diff --git a/src/test/java/org/opentripplanner/graph_builder/module/islandpruning/AdaptivePruningTest.java b/src/test/java/org/opentripplanner/graph_builder/module/islandpruning/AdaptivePruningTest.java index 832045b6469..90ffc33d848 100644 --- a/src/test/java/org/opentripplanner/graph_builder/module/islandpruning/AdaptivePruningTest.java +++ b/src/test/java/org/opentripplanner/graph_builder/module/islandpruning/AdaptivePruningTest.java @@ -1,37 +1,40 @@ package org.opentripplanner.graph_builder.module.islandpruning; -import java.io.File; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.opentripplanner.graph_builder.module.islandpruning.IslandPruningUtils.buildOsmGraph; + import java.util.stream.Collectors; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; -import org.opentripplanner.graph_builder.issue.api.DataImportIssueStore; -import org.opentripplanner.graph_builder.module.osm.OsmModule; -import org.opentripplanner.openstreetmap.OsmProvider; import org.opentripplanner.routing.graph.Graph; import org.opentripplanner.test.support.ResourceLoader; -import org.opentripplanner.transit.model.framework.Deduplicator; -import org.opentripplanner.transit.service.StopModel; -import org.opentripplanner.transit.service.TransitModel; -/* Test data consists of one bigger graph and two small sub graphs. These are totally disconnected. - One small graphs is only at 5 meter distance from the big graph and another one 30 m away. - Adaptive pruning retains the distant island but removes the closer one which appears to be - disconnected part of the main graph. +/** + * Test data consists of one bigger graph and two small sub graphs. These are totally disconnected. + * One small graphs is only at 5 meter distance from the big graph and another one 30 m away. + * Adaptive pruning retains the distant island but removes the closer one which appears to be + * disconnected part of the main graph. */ - public class AdaptivePruningTest { private static Graph graph; @BeforeAll static void setup() { - graph = buildOsmGraph(ResourceLoader.of(AdaptivePruningTest.class).file("isoiiluoto.pbf")); + graph = + buildOsmGraph( + ResourceLoader.of(AdaptivePruningTest.class).file("isoiiluoto.pbf"), + 5, + 0, + 20, + 30 + ); } @Test public void distantIslandIsRetained() { - Assertions.assertTrue( + assertTrue( graph .getStreetEdges() .stream() @@ -55,7 +58,7 @@ public void nearIslandIsRemoved() { @Test public void mainGraphIsNotRemoved() { - Assertions.assertTrue( + assertTrue( graph .getStreetEdges() .stream() @@ -64,42 +67,4 @@ public void mainGraphIsNotRemoved() { .contains("73347312") ); } - - private static Graph buildOsmGraph(File file) { - try { - var deduplicator = new Deduplicator(); - var graph = new Graph(deduplicator); - var transitModel = new TransitModel(new StopModel(), deduplicator); - // Add street data from OSM - OsmProvider osmProvider = new OsmProvider(file, true); - OsmModule osmModule = OsmModule.of(osmProvider, graph).withEdgeNamer(new TestNamer()).build(); - - osmModule.buildGraph(); - - transitModel.index(); - graph.index(transitModel.getStopModel()); - - // Prune floating islands and set noThru where necessary - PruneIslands pruneIslands = new PruneIslands( - graph, - transitModel, - DataImportIssueStore.NOOP, - null - ); - // all 3 sub graphs are larger than 5 edges - pruneIslands.setPruningThresholdIslandWithoutStops(5); - - // up to 5*20 = 100 edge graphs get pruned if they are too close - pruneIslands.setAdaptivePruningFactor(20); - - // Distant island is 30 m away from main graph, let's keep it - pruneIslands.setAdaptivePruningDistance(30); - - pruneIslands.buildGraph(); - - return graph; - } catch (Exception e) { - throw new RuntimeException(e); - } - } } diff --git a/src/test/java/org/opentripplanner/graph_builder/module/islandpruning/EscalatorPruningTest.java b/src/test/java/org/opentripplanner/graph_builder/module/islandpruning/EscalatorPruningTest.java new file mode 100644 index 00000000000..540befb07e0 --- /dev/null +++ b/src/test/java/org/opentripplanner/graph_builder/module/islandpruning/EscalatorPruningTest.java @@ -0,0 +1,30 @@ +package org.opentripplanner.graph_builder.module.islandpruning; + +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.opentripplanner.graph_builder.module.islandpruning.IslandPruningUtils.buildOsmGraph; + +import java.util.stream.Collectors; +import org.junit.jupiter.api.Test; +import org.opentripplanner.test.support.ResourceLoader; + +public class EscalatorPruningTest { + + @Test + public void streetEdgesBetweenEscalatorEdgesRetained() { + var graph = buildOsmGraph( + ResourceLoader.of(EscalatorPruningTest.class).file("matinkyla-escalator.pbf"), + 10, + 2, + 50, + 250 + ); + assertTrue( + graph + .getStreetEdges() + .stream() + .map(streetEdge -> streetEdge.getName().toString()) + .collect(Collectors.toSet()) + .contains("490072445") + ); + } +} diff --git a/src/test/java/org/opentripplanner/graph_builder/module/islandpruning/IslandPruningUtils.java b/src/test/java/org/opentripplanner/graph_builder/module/islandpruning/IslandPruningUtils.java new file mode 100644 index 00000000000..59362472771 --- /dev/null +++ b/src/test/java/org/opentripplanner/graph_builder/module/islandpruning/IslandPruningUtils.java @@ -0,0 +1,52 @@ +package org.opentripplanner.graph_builder.module.islandpruning; + +import java.io.File; +import org.opentripplanner.graph_builder.issue.api.DataImportIssueStore; +import org.opentripplanner.graph_builder.module.osm.OsmModule; +import org.opentripplanner.openstreetmap.OsmProvider; +import org.opentripplanner.routing.graph.Graph; +import org.opentripplanner.transit.model.framework.Deduplicator; +import org.opentripplanner.transit.service.StopModel; +import org.opentripplanner.transit.service.TransitModel; + +class IslandPruningUtils { + + static Graph buildOsmGraph( + File osmFile, + int thresholdIslandWithoutStops, + int thresholdIslandWithStops, + double adaptivePruningFactor, + int adaptivePruningDistance + ) { + try { + var deduplicator = new Deduplicator(); + var graph = new Graph(deduplicator); + var transitModel = new TransitModel(new StopModel(), deduplicator); + // Add street data from OSM + OsmProvider osmProvider = new OsmProvider(osmFile, true); + OsmModule osmModule = OsmModule.of(osmProvider, graph).withEdgeNamer(new TestNamer()).build(); + + osmModule.buildGraph(); + + transitModel.index(); + graph.index(transitModel.getStopModel()); + + // Prune floating islands and set noThru where necessary + PruneIslands pruneIslands = new PruneIslands( + graph, + transitModel, + DataImportIssueStore.NOOP, + null + ); + pruneIslands.setPruningThresholdIslandWithoutStops(thresholdIslandWithoutStops); + pruneIslands.setPruningThresholdIslandWithStops(thresholdIslandWithStops); + pruneIslands.setAdaptivePruningFactor(adaptivePruningFactor); + pruneIslands.setAdaptivePruningDistance(adaptivePruningDistance); + pruneIslands.buildGraph(); + + return graph; + } catch (Exception e) { + throw new RuntimeException(e); + } + } +} diff --git a/src/test/java/org/opentripplanner/graph_builder/module/islandpruning/PruneNoThruIslandsTest.java b/src/test/java/org/opentripplanner/graph_builder/module/islandpruning/PruneNoThruIslandsTest.java index 53a2d60fe0f..9070fb00f8f 100644 --- a/src/test/java/org/opentripplanner/graph_builder/module/islandpruning/PruneNoThruIslandsTest.java +++ b/src/test/java/org/opentripplanner/graph_builder/module/islandpruning/PruneNoThruIslandsTest.java @@ -1,20 +1,16 @@ package org.opentripplanner.graph_builder.module.islandpruning; -import java.io.File; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.opentripplanner.graph_builder.module.islandpruning.IslandPruningUtils.buildOsmGraph; + import java.util.Set; import java.util.stream.Collectors; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; -import org.opentripplanner.graph_builder.issue.api.DataImportIssueStore; -import org.opentripplanner.graph_builder.module.osm.OsmModule; -import org.opentripplanner.openstreetmap.OsmProvider; import org.opentripplanner.routing.graph.Graph; import org.opentripplanner.street.model.edge.StreetEdge; import org.opentripplanner.test.support.ResourceLoader; -import org.opentripplanner.transit.model.framework.Deduplicator; -import org.opentripplanner.transit.service.StopModel; -import org.opentripplanner.transit.service.TransitModel; public class PruneNoThruIslandsTest { @@ -26,13 +22,17 @@ static void setup() { buildOsmGraph( ResourceLoader .of(PruneNoThruIslandsTest.class) - .file("herrenberg-island-prune-nothru.osm.pbf") + .file("herrenberg-island-prune-nothru.osm.pbf"), + 10, + 2, + 50, + 250 ); } @Test public void bicycleIslandsBecomeNoThru() { - Assertions.assertTrue( + assertTrue( graph .getStreetEdges() .stream() @@ -45,7 +45,7 @@ public void bicycleIslandsBecomeNoThru() { @Test public void carIslandsBecomeNoThru() { - Assertions.assertTrue( + assertTrue( graph .getStreetEdges() .stream() @@ -67,36 +67,4 @@ public void pruneFloatingBikeAndWalkIsland() { .contains("159830257") ); } - - private static Graph buildOsmGraph(File osmFile) { - try { - var deduplicator = new Deduplicator(); - var graph = new Graph(deduplicator); - var transitModel = new TransitModel(new StopModel(), deduplicator); - // Add street data from OSM - OsmProvider osmProvider = new OsmProvider(osmFile, true); - OsmModule osmModule = OsmModule.of(osmProvider, graph).withEdgeNamer(new TestNamer()).build(); - - osmModule.buildGraph(); - - transitModel.index(); - graph.index(transitModel.getStopModel()); - - // Prune floating islands and set noThru where necessary - PruneIslands pruneIslands = new PruneIslands( - graph, - transitModel, - DataImportIssueStore.NOOP, - null - ); - pruneIslands.setPruningThresholdIslandWithoutStops(40); - pruneIslands.setPruningThresholdIslandWithStops(5); - pruneIslands.setAdaptivePruningFactor(1); - pruneIslands.buildGraph(); - - return graph; - } catch (Exception e) { - throw new RuntimeException(e); - } - } } diff --git a/src/test/java/org/opentripplanner/netex/mapping/TripPatternMapperTest.java b/src/test/java/org/opentripplanner/netex/mapping/TripPatternMapperTest.java index f07a46ced2c..74448fb3638 100644 --- a/src/test/java/org/opentripplanner/netex/mapping/TripPatternMapperTest.java +++ b/src/test/java/org/opentripplanner/netex/mapping/TripPatternMapperTest.java @@ -1,9 +1,11 @@ package org.opentripplanner.netex.mapping; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; import com.google.common.collect.ArrayListMultimap; import java.util.Map; +import java.util.Optional; import org.junit.jupiter.api.Test; import org.opentripplanner.graph_builder.issue.api.DataImportIssueStore; import org.opentripplanner.netex.index.hierarchy.HierarchicalMap; @@ -12,7 +14,6 @@ import org.opentripplanner.transit.model.framework.Deduplicator; import org.opentripplanner.transit.model.framework.DefaultEntityById; import org.opentripplanner.transit.model.framework.FeedScopedId; -import org.opentripplanner.transit.model.network.TripPattern; import org.opentripplanner.transit.model.timetable.Trip; import org.opentripplanner.transit.model.timetable.TripAlteration; import org.opentripplanner.transit.model.timetable.TripOnServiceDate; @@ -55,26 +56,28 @@ public void testMapTripPattern() { 150 ); - TripPatternMapperResult r = tripPatternMapper.mapTripPattern(sample.getJourneyPattern()); + Optional res = tripPatternMapper.mapTripPattern( + sample.getJourneyPattern() + ); - assertEquals(1, r.tripPatterns.size()); + assertTrue(res.isPresent()); - TripPattern tripPattern = r.tripPatterns.values().stream().findFirst().orElseThrow(); + TripPatternMapperResult r = res.get(); - assertEquals(4, tripPattern.numberOfStops()); - assertEquals(1, tripPattern.scheduledTripsAsStream().count()); + assertEquals(4, r.tripPattern().numberOfStops()); + assertEquals(1, r.tripPattern().scheduledTripsAsStream().count()); - Trip trip = tripPattern.scheduledTripsAsStream().findFirst().get(); + Trip trip = r.tripPattern().scheduledTripsAsStream().findFirst().get(); assertEquals("RUT:ServiceJourney:1", trip.getId().getId()); - assertEquals("NSR:Quay:1", tripPattern.getStop(0).getId().getId()); - assertEquals("NSR:Quay:2", tripPattern.getStop(1).getId().getId()); - assertEquals("NSR:Quay:3", tripPattern.getStop(2).getId().getId()); - assertEquals("NSR:Quay:4", tripPattern.getStop(3).getId().getId()); + assertEquals("NSR:Quay:1", r.tripPattern().getStop(0).getId().getId()); + assertEquals("NSR:Quay:2", r.tripPattern().getStop(1).getId().getId()); + assertEquals("NSR:Quay:3", r.tripPattern().getStop(2).getId().getId()); + assertEquals("NSR:Quay:4", r.tripPattern().getStop(3).getId().getId()); - assertEquals(1, tripPattern.getScheduledTimetable().getTripTimes().size()); + assertEquals(1, r.tripPattern().getScheduledTimetable().getTripTimes().size()); - TripTimes tripTimes = tripPattern.getScheduledTimetable().getTripTimes().get(0); + TripTimes tripTimes = r.tripPattern().getScheduledTimetable().getTripTimes().get(0); assertEquals(4, tripTimes.getNumStops()); @@ -115,15 +118,19 @@ public void testMapTripPattern_datedServiceJourney() { 150 ); - TripPatternMapperResult r = tripPatternMapper.mapTripPattern(sample.getJourneyPattern()); + Optional res = tripPatternMapper.mapTripPattern( + sample.getJourneyPattern() + ); + + assertTrue(res.isPresent()); + + var r = res.get(); - assertEquals(1, r.tripPatterns.size()); - assertEquals(2, r.tripOnServiceDates.size()); + assertEquals(2, r.tripOnServiceDates().size()); - TripPattern tripPattern = r.tripPatterns.values().stream().findFirst().orElseThrow(); - Trip trip = tripPattern.scheduledTripsAsStream().findFirst().get(); + Trip trip = r.tripPattern().scheduledTripsAsStream().findFirst().get(); - for (TripOnServiceDate tripOnServiceDate : r.tripOnServiceDates) { + for (TripOnServiceDate tripOnServiceDate : r.tripOnServiceDates()) { assertEquals(trip, tripOnServiceDate.getTrip()); assertEquals(TripAlteration.PLANNED, tripOnServiceDate.getTripAlteration()); assertEquals( diff --git a/src/test/java/org/opentripplanner/raptor/_data/api/TestPathBuilderTestRaptor.java b/src/test/java/org/opentripplanner/raptor/_data/api/TestPathBuilderTestRaptor.java index bc11f32e4cc..de40c29d583 100644 --- a/src/test/java/org/opentripplanner/raptor/_data/api/TestPathBuilderTestRaptor.java +++ b/src/test/java/org/opentripplanner/raptor/_data/api/TestPathBuilderTestRaptor.java @@ -1,6 +1,7 @@ package org.opentripplanner.raptor._data.api; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; import static org.opentripplanner.framework.time.DurationUtils.durationInSeconds; import static org.opentripplanner.framework.time.TimeUtils.time; import static org.opentripplanner.model.transfer.TransferConstraint.REGULAR_TRANSFER; @@ -84,14 +85,12 @@ public void testBasicPath() { ) .egress(BasicPathTestCase.EGRESS_DURATION); - Assertions.assertEquals( - BasicPathTestCase.BASIC_PATH_AS_STRING, - path.toString(this::stopIndexToName) - ); - Assertions.assertEquals( + assertEquals(BasicPathTestCase.BASIC_PATH_AS_STRING, path.toString(this::stopIndexToName)); + assertEquals( BasicPathTestCase.BASIC_PATH_AS_DETAILED_STRING, path.toStringDetailed(this::stopIndexToName) ); - Assertions.assertEquals(BasicPathTestCase.TOTAL_C1, path.c1()); + assertEquals(BasicPathTestCase.TOTAL_C1, path.c1()); + assertTrue(path.isC2Set()); } } diff --git a/src/test/java/org/opentripplanner/raptor/moduletests/K01_TransitPriorityTest.java b/src/test/java/org/opentripplanner/raptor/moduletests/K01_TransitPriorityTest.java index be544f26a11..c1db11be779 100644 --- a/src/test/java/org/opentripplanner/raptor/moduletests/K01_TransitPriorityTest.java +++ b/src/test/java/org/opentripplanner/raptor/moduletests/K01_TransitPriorityTest.java @@ -67,13 +67,20 @@ public DominanceFunction dominanceFunction() { RaptorConfig.defaultConfigForTest() ); + /** + * Each pattern departs at the same time, but arrives at different times. They may belong to + * different groups. Line U1 is not optimal, because it slower than L1 and is in the same + * group as L1. Given a slack on the cost equals to ~90s makes both L1 and L2 optimal (since + * they are in different groups), but not L3 (which is in its own group, but its cost is + * outside the range allowed by the slack). + */ @BeforeEach private void prepareRequest() { - // Each pattern depart at the same time, but arrive with 60s between them. - // Given a slack on the cost equals to ~90s make both L1 and L2 optimal, but no L3 data.withRoutes( route(pattern("L1", STOP_B, STOP_C).withPriorityGroup(GROUP_A)) .withTimetable(schedule("00:02 00:12")), + route(pattern("U1", STOP_B, STOP_C).withPriorityGroup(GROUP_A)) + .withTimetable(schedule("00:02 00:12:01")), route(pattern("L2", STOP_B, STOP_C).withPriorityGroup(GROUP_B)) .withTimetable(schedule("00:02 00:13")), route(pattern("L3", STOP_B, STOP_C).withPriorityGroup(GROUP_C)) diff --git a/src/test/java/org/opentripplanner/raptor/moduletests/K02_TransitPriorityDestinationTest.java b/src/test/java/org/opentripplanner/raptor/moduletests/K02_TransitPriorityDestinationTest.java new file mode 100644 index 00000000000..c7b64cb5b9e --- /dev/null +++ b/src/test/java/org/opentripplanner/raptor/moduletests/K02_TransitPriorityDestinationTest.java @@ -0,0 +1,151 @@ +package org.opentripplanner.raptor.moduletests; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.opentripplanner.raptor._data.RaptorTestConstants.STOP_B; +import static org.opentripplanner.raptor._data.RaptorTestConstants.STOP_C; +import static org.opentripplanner.raptor._data.RaptorTestConstants.STOP_D; +import static org.opentripplanner.raptor._data.RaptorTestConstants.STOP_E; +import static org.opentripplanner.raptor._data.RaptorTestConstants.STOP_F; +import static org.opentripplanner.raptor._data.RaptorTestConstants.STOP_G; +import static org.opentripplanner.raptor._data.RaptorTestConstants.T00_00; +import static org.opentripplanner.raptor._data.RaptorTestConstants.T01_00; +import static org.opentripplanner.raptor._data.api.PathUtils.pathsToString; +import static org.opentripplanner.raptor._data.transit.TestAccessEgress.walk; +import static org.opentripplanner.raptor._data.transit.TestRoute.route; +import static org.opentripplanner.raptor._data.transit.TestTripPattern.pattern; +import static org.opentripplanner.raptor._data.transit.TestTripSchedule.schedule; + +import java.time.Duration; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.opentripplanner.raptor.RaptorService; +import org.opentripplanner.raptor._data.transit.TestTransitData; +import org.opentripplanner.raptor._data.transit.TestTripSchedule; +import org.opentripplanner.raptor.api.model.DominanceFunction; +import org.opentripplanner.raptor.api.request.RaptorProfile; +import org.opentripplanner.raptor.api.request.RaptorRequestBuilder; +import org.opentripplanner.raptor.api.request.RaptorTransitPriorityGroupCalculator; +import org.opentripplanner.raptor.configure.RaptorConfig; +import org.opentripplanner.routing.algorithm.raptoradapter.transit.cost.RaptorCostConverter; + +/** + * FEATURE UNDER TEST + * + * Raptor should be able to handle route request with transit-priority. + */ +public class K02_TransitPriorityDestinationTest { + + private static final RaptorTransitPriorityGroupCalculator PRIORITY_GROUP_CALCULATOR = new RaptorTransitPriorityGroupCalculator() { + @Override + public int mergeTransitPriorityGroupIds(int currentGroupIds, int boardingGroupId) { + return currentGroupIds | boardingGroupId; + } + + /** + * Left dominate right, if right has at least one priority group not in left. + */ + @Override + public DominanceFunction dominanceFunction() { + return (l, r) -> ((l ^ r) & r) != 0; + } + }; + + private static final int GROUP_A = 0x01; + private static final int GROUP_B = 0x02; + private static final int GROUP_C = 0x04; + private static final int GROUP_AB = PRIORITY_GROUP_CALCULATOR.mergeTransitPriorityGroupIds( + GROUP_A, + GROUP_B + ); + private static final int GROUP_AC = PRIORITY_GROUP_CALCULATOR.mergeTransitPriorityGroupIds( + GROUP_A, + GROUP_C + ); + private static final int C1_SLACK_90s = RaptorCostConverter.toRaptorCost(90); + + private final TestTransitData data = new TestTransitData(); + private final RaptorRequestBuilder requestBuilder = new RaptorRequestBuilder<>(); + private final RaptorService raptorService = new RaptorService<>( + RaptorConfig.defaultConfigForTest() + ); + + @BeforeEach + private void prepareRequest() { + // Each pattern depart at the same time, but arrive at different times and they may + // belong to different groups. + // Line U1 is not optimal, because it slower than L1 and is in the same group. + // Given a slack on the cost equals to ~90s this makes both L1 and L2 optimal (since + // they are in different groups), but not L3 (which certainly is in its own group but + // its cost is outside the range allowed by the slack). + data.withRoutes( + route(pattern("L1", STOP_B, STOP_C).withPriorityGroup(GROUP_A)) + .withTimetable(schedule("00:02 00:12")), + route(pattern("U1", STOP_B, STOP_D).withPriorityGroup(GROUP_A)) + .withTimetable(schedule("00:02 00:12:01")), + route(pattern("L2", STOP_B, STOP_E).withPriorityGroup(GROUP_B)) + .withTimetable(schedule("00:02 00:13")), + route(pattern("L3", STOP_B, STOP_F).withPriorityGroup(GROUP_C)) + .withTimetable(schedule("00:02 00:14")) + ); + + requestBuilder + .profile(RaptorProfile.MULTI_CRITERIA) + // TODO: 2023-07-24 Currently heuristics does not work with pass-through so we + // have to turn them off. Make sure to re-enable optimization later when it's fixed + .clearOptimizations(); + + requestBuilder + .searchParams() + .earliestDepartureTime(T00_00) + .latestArrivalTime(T01_00) + .searchWindow(Duration.ofMinutes(2)) + .timetable(true); + + requestBuilder.withMultiCriteria(mc -> + // Raptor cost 9000 ~= 90 seconds slack + mc + .withRelaxC1(value -> value + C1_SLACK_90s) + .withTransitPriorityCalculator(PRIORITY_GROUP_CALCULATOR) + ); + // Add 1 second access/egress paths + requestBuilder + .searchParams() + .addAccessPaths(walk(STOP_B, 1)) + .addEgressPaths(walk(STOP_C, 1)) + .addEgressPaths(walk(STOP_D, 1)) + .addEgressPaths(walk(STOP_E, 1)) + .addEgressPaths(walk(STOP_F, 1)); + assetGroupCalculatorIsSetupCorrect(); + } + + @Test + public void transitPriority() { + // We expect L1 & L2 but not L3, since the cost of L3 is > $90.00. + assertEquals( + """ + Walk 1s ~ B ~ BUS L1 0:02 0:12 ~ C ~ Walk 1s [0:01:59 0:12:01 10m2s Tₓ0 C₁1_204 C₂1] + Walk 1s ~ B ~ BUS L2 0:02 0:13 ~ E ~ Walk 1s [0:01:59 0:13:01 11m2s Tₓ0 C₁1_264 C₂2] + """.trim(), + pathsToString(raptorService.route(requestBuilder.build(), data)) + ); + } + + /** + * Make sure the calculator and group setup is done correct. + */ + void assetGroupCalculatorIsSetupCorrect() { + var d = PRIORITY_GROUP_CALCULATOR.dominanceFunction(); + + assertTrue(d.leftDominateRight(GROUP_A, GROUP_B)); + assertTrue(d.leftDominateRight(GROUP_B, GROUP_A)); + assertFalse(d.leftDominateRight(GROUP_A, GROUP_A)); + // 3 = 1&2, 5 = 1&4 + assertTrue(d.leftDominateRight(GROUP_A, GROUP_AB)); + assertFalse(d.leftDominateRight(GROUP_AB, GROUP_A)); + assertFalse(d.leftDominateRight(GROUP_AB, GROUP_AB)); + assertTrue(d.leftDominateRight(GROUP_AB, GROUP_AC)); + assertTrue(d.leftDominateRight(GROUP_AC, GROUP_AB)); + } +} diff --git a/src/test/java/org/opentripplanner/raptor/rangeraptor/context/SearchContextTest.java b/src/test/java/org/opentripplanner/raptor/rangeraptor/context/SearchContextTest.java index 8ac0af5b3a8..4ffa4ed1cd9 100644 --- a/src/test/java/org/opentripplanner/raptor/rangeraptor/context/SearchContextTest.java +++ b/src/test/java/org/opentripplanner/raptor/rangeraptor/context/SearchContextTest.java @@ -1,9 +1,14 @@ package org.opentripplanner.raptor.rangeraptor.context; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.opentripplanner.raptor.api.model.SearchDirection.FORWARD; +import static org.opentripplanner.raptor.api.model.SearchDirection.REVERSE; import static org.opentripplanner.raptor.api.request.RaptorProfile.MULTI_CRITERIA; import static org.opentripplanner.raptor.api.request.RaptorProfile.STANDARD; import static org.opentripplanner.raptor.rangeraptor.context.SearchContext.accessOrEgressPaths; +import static org.opentripplanner.raptor.rangeraptor.internalapi.ParetoSetTime.USE_ARRIVAL_TIME; +import static org.opentripplanner.raptor.rangeraptor.internalapi.ParetoSetTime.USE_DEPARTURE_TIME; +import static org.opentripplanner.raptor.rangeraptor.internalapi.ParetoSetTime.USE_TIMETABLE; import java.util.Collection; import java.util.Comparator; @@ -11,14 +16,20 @@ import java.util.stream.Collectors; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; import org.opentripplanner.raptor._data.RaptorTestConstants; import org.opentripplanner.raptor._data.transit.TestAccessEgress; import org.opentripplanner.raptor._data.transit.TestTripSchedule; import org.opentripplanner.raptor.api.model.RaptorAccessEgress; +import org.opentripplanner.raptor.api.model.SearchDirection; import org.opentripplanner.raptor.api.request.RaptorRequestBuilder; +import org.opentripplanner.raptor.rangeraptor.internalapi.ParetoSetTime; class SearchContextTest implements RaptorTestConstants { + public static final TestAccessEgress ANY_WALK = TestAccessEgress.walk(1, 1); private final boolean GET_ACCESS = true; private final boolean GET_EGRESS = false; private final RaptorAccessEgress PATH_A_10s = TestAccessEgress.walk(STOP_A, D10s); @@ -82,4 +93,43 @@ private static List sort(Collection c) { .sorted(Comparator.comparingInt(it -> it.stop() * 10_000 + it.durationInSeconds())) .collect(Collectors.toList()); } + + static List paretoSetTimeConfigTestCase() { + return List.of( + Arguments.of(USE_TIMETABLE, true, false, FORWARD), + Arguments.of(USE_TIMETABLE, true, false, REVERSE), + Arguments.of(USE_DEPARTURE_TIME, false, true, FORWARD), + Arguments.of(USE_DEPARTURE_TIME, false, false, REVERSE), + Arguments.of(USE_ARRIVAL_TIME, false, true, REVERSE), + Arguments.of(USE_ARRIVAL_TIME, false, false, FORWARD) + ); + } + + @ParameterizedTest + @MethodSource("paretoSetTimeConfigTestCase") + void testParetoSetTimeConfig( + ParetoSetTime expected, + boolean timetable, + boolean prefLateArrival, + SearchDirection searchDirection + ) { + assertEquals( + expected, + SearchContext.paretoSetTimeConfig( + new RaptorRequestBuilder() + .searchParams() + // EDT, LAT, access and egress is required, but not used + .addAccessPaths(ANY_WALK) + .addEgressPaths(ANY_WALK) + .earliestDepartureTime(12) + .latestArrivalTime(120) + // Relevant parameters + .timetable(timetable) + .preferLateArrival(prefLateArrival) + .build() + .searchParams(), + searchDirection + ) + ); + } } diff --git a/src/test/java/org/opentripplanner/raptor/rangeraptor/path/PathParetoSetComparatorsTest.java b/src/test/java/org/opentripplanner/raptor/rangeraptor/path/PathParetoSetComparatorsTest.java index d8d5ddfb472..296103499a1 100644 --- a/src/test/java/org/opentripplanner/raptor/rangeraptor/path/PathParetoSetComparatorsTest.java +++ b/src/test/java/org/opentripplanner/raptor/rangeraptor/path/PathParetoSetComparatorsTest.java @@ -2,8 +2,20 @@ import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; - -import org.junit.jupiter.api.Test; +import static org.opentripplanner.raptor.rangeraptor.internalapi.ParetoSetCost.NONE; +import static org.opentripplanner.raptor.rangeraptor.internalapi.ParetoSetCost.USE_C1; +import static org.opentripplanner.raptor.rangeraptor.internalapi.ParetoSetCost.USE_C1_AND_C2; +import static org.opentripplanner.raptor.rangeraptor.internalapi.ParetoSetCost.USE_C1_RELAXED_IF_C2_IS_OPTIMAL; +import static org.opentripplanner.raptor.rangeraptor.internalapi.ParetoSetCost.USE_C1_RELAX_DESTINATION; +import static org.opentripplanner.raptor.rangeraptor.internalapi.ParetoSetTime.USE_ARRIVAL_TIME; +import static org.opentripplanner.raptor.rangeraptor.internalapi.ParetoSetTime.USE_DEPARTURE_TIME; +import static org.opentripplanner.raptor.rangeraptor.internalapi.ParetoSetTime.USE_TIMETABLE; +import static org.opentripplanner.raptor.rangeraptor.path.PathParetoSetComparators.paretoComparator; + +import java.util.List; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; import org.opentripplanner.raptor._data.api.TestRaptorPath; import org.opentripplanner.raptor.api.model.DominanceFunction; import org.opentripplanner.raptor.api.model.GeneralizedCostRelaxFunction; @@ -11,325 +23,93 @@ import org.opentripplanner.raptor.api.model.RelaxFunction; import org.opentripplanner.raptor.api.model.SearchDirection; import org.opentripplanner.raptor.api.path.RaptorPath; +import org.opentripplanner.raptor.rangeraptor.internalapi.ParetoSetCost; +import org.opentripplanner.raptor.rangeraptor.internalapi.ParetoSetTime; import org.opentripplanner.raptor.util.paretoset.ParetoComparator; public class PathParetoSetComparatorsTest { - final int BIG_VALUE = 999; - final int SMALL_VALUE = 100; - final int NO_VALUE = 0; - - private final DominanceFunction DOMINANCE_FUNCTION = (left, right) -> left > right; - private final RelaxFunction RELAX_FUNCTION = GeneralizedCostRelaxFunction.of(1.5, 0); - - @Test - public void testComparatorStandardArrivalTime() { - var comparator = PathParetoSetComparators.paretoComparator( - false, - false, - false, - SearchDirection.FORWARD, - RelaxFunction.NORMAL, - null - ); - - verifyEndTimeComparator(comparator); - verifyNumberOfTransfers(comparator); - } - - @Test - public void testComparatorStandardArrivalTimeAndC2() { - var comparator = PathParetoSetComparators.paretoComparator( - false, - false, - false, - SearchDirection.FORWARD, - RelaxFunction.NORMAL, - DOMINANCE_FUNCTION - ); - - verifyEndTimeComparator(comparator); - verifyNumberOfTransfers(comparator); - verifyC2Comparator(comparator); - } - - @Test - public void testComparatorStandardDepartureTime() { - var comparator = PathParetoSetComparators.paretoComparator( - false, - false, - true, - SearchDirection.FORWARD, - RelaxFunction.NORMAL, - null - ); - - verifyStartTimeComparator(comparator); - - verifyNumberOfTransfers(comparator); - } - - @Test - public void testComparatorStandardDepartureTimeAndC2() { - var comparator = PathParetoSetComparators.paretoComparator( - false, - false, - true, - SearchDirection.FORWARD, - RelaxFunction.NORMAL, - DOMINANCE_FUNCTION - ); - - verifyStartTimeComparator(comparator); - verifyNumberOfTransfers(comparator); - verifyC2Comparator(comparator); - } - - @Test - public void testComparatorTimetable() { - var comparator = PathParetoSetComparators.paretoComparator( - false, - true, - false, - SearchDirection.FORWARD, - RelaxFunction.NORMAL, - null - ); - - verifyRangeRaptorIterationDepartureTime(comparator); - verifyEndTimeComparator(comparator); - verifyNumberOfTransfers(comparator); - } - - @Test - public void testComparatorTimetableAndC2() { - var comparator = PathParetoSetComparators.paretoComparator( - false, - true, - false, - SearchDirection.FORWARD, - RelaxFunction.NORMAL, - DOMINANCE_FUNCTION - ); - - verifyRangeRaptorIterationDepartureTime(comparator); - verifyEndTimeComparator(comparator); - verifyNumberOfTransfers(comparator); - verifyC2Comparator(comparator); - } - - @Test - public void testComparatorTimetableAndC1() { - var comparator = PathParetoSetComparators.paretoComparator( - true, - true, - false, - SearchDirection.FORWARD, - RelaxFunction.NORMAL, - null - ); - - verifyRangeRaptorIterationDepartureTime(comparator); - verifyEndTimeComparator(comparator); - verifyNumberOfTransfers(comparator); - verifyDurationComparator(comparator); - verifyC1Comparator(comparator); - } - - @Test - public void testComparatorTimetableAndRelaxedC1() { - var comparator = PathParetoSetComparators.paretoComparator( - true, - true, - false, - SearchDirection.FORWARD, - RELAX_FUNCTION, - null - ); - - verifyRangeRaptorIterationDepartureTime(comparator); - verifyEndTimeComparator(comparator); - verifyNumberOfTransfers(comparator); - verifyDurationComparator(comparator); - verifyRelaxedC1Comparator(comparator); - } - - @Test - public void testComparatorWithC1() { - var comparator = PathParetoSetComparators.paretoComparator( - true, - false, - false, - SearchDirection.FORWARD, - RelaxFunction.NORMAL, - null - ); - - verifyEndTimeComparator(comparator); - verifyNumberOfTransfers(comparator); - verifyDurationComparator(comparator); - verifyC1Comparator(comparator); - } - - @Test - public void testComparatorDepartureTimeAndC1() { - var comparator = PathParetoSetComparators.paretoComparator( - true, - false, - true, - SearchDirection.FORWARD, - RelaxFunction.NORMAL, - null - ); - - verifyStartTimeComparator(comparator); - verifyNumberOfTransfers(comparator); - verifyDurationComparator(comparator); - verifyC1Comparator(comparator); - } - - @Test - public void comparatorArrivalTimeAndRelaxedC1() { - var comparator = PathParetoSetComparators.paretoComparator( - true, - false, - false, - SearchDirection.FORWARD, - RELAX_FUNCTION, - null - ); - - verifyEndTimeComparator(comparator); - verifyNumberOfTransfers(comparator); - verifyDurationComparator(comparator); - verifyRelaxedC1Comparator(comparator); - } - - @Test - public void testComparatorDepartureTimeAndRelaxedC1() { - var comparator = PathParetoSetComparators.paretoComparator( - true, - false, - true, - SearchDirection.FORWARD, - RELAX_FUNCTION, - null - ); - - verifyStartTimeComparator(comparator); - verifyNumberOfTransfers(comparator); - verifyDurationComparator(comparator); - verifyRelaxedC1Comparator(comparator); - } - - @Test - public void testComparatorTimetableAndC1AndC2() { - var comparator = PathParetoSetComparators.paretoComparator( - true, - true, - false, - SearchDirection.FORWARD, - RelaxFunction.NORMAL, - DOMINANCE_FUNCTION - ); - - verifyRangeRaptorIterationDepartureTime(comparator); - verifyEndTimeComparator(comparator); - verifyNumberOfTransfers(comparator); - verifyDurationComparator(comparator); - verifyC1Comparator(comparator); - verifyC2Comparator(comparator); - } - - @Test - public void testComparatorTimetableAndRelaxedC1AndC2() { - var comparator = PathParetoSetComparators.paretoComparator( - true, - true, - false, - SearchDirection.FORWARD, - RELAX_FUNCTION, - DOMINANCE_FUNCTION + private static final int ANY = 0; + private static final int NORMAL = 100; + private static final int SMALL = 50; + private static final int LARGE = 999; + private static final int RELAXED = 140; + private static final int RELAXED_DELTA_LIMIT = 50; + + private static final DominanceFunction DOMINANCE_FN = (left, right) -> left < right; + private static final DominanceFunction NO_COMP = null; + + private static final RelaxFunction RELAX_FN = GeneralizedCostRelaxFunction.of( + 1.0, + RELAXED_DELTA_LIMIT + ); + private static final RelaxFunction NO_RELAX_FN = RelaxFunction.NORMAL; + + static List testCases() { + return List.of( + // Arrival time + Arguments.of(USE_ARRIVAL_TIME, NONE, NO_RELAX_FN, NO_COMP), + Arguments.of(USE_ARRIVAL_TIME, USE_C1, NO_RELAX_FN, NO_COMP), + Arguments.of(USE_ARRIVAL_TIME, USE_C1_AND_C2, NO_RELAX_FN, DOMINANCE_FN), + // TODO: This is failing, error in implementation + Arguments.of(USE_ARRIVAL_TIME, USE_C1_RELAXED_IF_C2_IS_OPTIMAL, RELAX_FN, DOMINANCE_FN), + Arguments.of(USE_ARRIVAL_TIME, USE_C1_RELAX_DESTINATION, RELAX_FN, NO_COMP), + // Departure time + Arguments.of(USE_DEPARTURE_TIME, NONE, NO_RELAX_FN, NO_COMP), + Arguments.of(USE_DEPARTURE_TIME, USE_C1_AND_C2, NO_RELAX_FN, DOMINANCE_FN), + // TODO: This is failing, error in implementation + Arguments.of(USE_DEPARTURE_TIME, USE_C1_RELAXED_IF_C2_IS_OPTIMAL, RELAX_FN, DOMINANCE_FN), + Arguments.of(USE_DEPARTURE_TIME, USE_C1_RELAX_DESTINATION, RELAX_FN, NO_COMP), + // Timetable + Arguments.of(USE_TIMETABLE, NONE, NO_RELAX_FN, NO_COMP), + Arguments.of(USE_TIMETABLE, USE_C1_AND_C2, NO_RELAX_FN, DOMINANCE_FN), + // TODO: This is failing, error in implementation + Arguments.of(USE_TIMETABLE, USE_C1_RELAXED_IF_C2_IS_OPTIMAL, RELAX_FN, DOMINANCE_FN), + Arguments.of(USE_TIMETABLE, USE_C1_RELAX_DESTINATION, RELAX_FN, NO_COMP) ); - - verifyRangeRaptorIterationDepartureTime(comparator); - verifyEndTimeComparator(comparator); - verifyNumberOfTransfers(comparator); - verifyDurationComparator(comparator); - verifyRelaxedC1Comparator(comparator); - verifyC2Comparator(comparator); - } - - @Test - public void testComparatorWithC1AndC2() { - var comparator = PathParetoSetComparators.paretoComparator( - true, - false, - false, - SearchDirection.FORWARD, - RelaxFunction.NORMAL, - DOMINANCE_FUNCTION - ); - - verifyEndTimeComparator(comparator); - verifyNumberOfTransfers(comparator); - verifyDurationComparator(comparator); - verifyC1Comparator(comparator); - verifyC2Comparator(comparator); } - @Test - public void testComparatorDepartureTimeAndC1AndC2() { - var comparator = PathParetoSetComparators.paretoComparator( - true, - false, - true, - SearchDirection.FORWARD, - RelaxFunction.NORMAL, - DOMINANCE_FUNCTION - ); - - verifyStartTimeComparator(comparator); - verifyNumberOfTransfers(comparator); - verifyDurationComparator(comparator); - verifyC1Comparator(comparator); - verifyC2Comparator(comparator); - } - - @Test - public void testComparatorArrivalTimeAndRelaxedC1AndC2() { - var comparator = PathParetoSetComparators.paretoComparator( - true, - false, - false, - SearchDirection.FORWARD, - RELAX_FUNCTION, - DOMINANCE_FUNCTION - ); - - verifyEndTimeComparator(comparator); - verifyNumberOfTransfers(comparator); - verifyDurationComparator(comparator); - verifyRelaxedC1Comparator(comparator); - verifyC2Comparator(comparator); - } - - @Test - public void testComparatorDepartureTimeAndRelaxedC1AndC2() { - var comparator = PathParetoSetComparators.paretoComparator( - true, - false, - true, - SearchDirection.FORWARD, - RELAX_FUNCTION, - DOMINANCE_FUNCTION - ); - - verifyStartTimeComparator(comparator); + @ParameterizedTest + @MethodSource("testCases") + public void testComparator( + ParetoSetTime time, + ParetoSetCost cost, + RelaxFunction relaxC1, + DominanceFunction comp2 + ) { + var comparator = paretoComparator(time, cost, relaxC1, comp2); verifyNumberOfTransfers(comparator); - verifyDurationComparator(comparator); - verifyRelaxedC1Comparator(comparator); - verifyC2Comparator(comparator); + switch (time) { + case USE_ARRIVAL_TIME: + verifyEndTimeComparator(comparator); + break; + case USE_DEPARTURE_TIME: + verifyStartTimeComparator(comparator); + break; + case USE_TIMETABLE: + verifyIterationDepartureTime(comparator); + verifyEndTimeComparator(comparator); + break; + } + + switch (cost) { + case USE_C1: + verifyC1Comparator(comparator); + break; + case USE_C1_AND_C2: + verifyC1Comparator(comparator); + verifyC2Comparator(comparator); + break; + case USE_C1_RELAXED_IF_C2_IS_OPTIMAL: + verifyRelaxedC1IfC2Optimal(comparator); + break; + case USE_C1_RELAX_DESTINATION: + verifyRelaxedC1Comparator(comparator); + break; + case NONE: + default: + break; + } } /** @@ -340,14 +120,14 @@ private void verifyStartTimeComparator( ) { assertTrue( comparator.leftDominanceExist( - new TestRaptorPath(NO_VALUE, BIG_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE), - new TestRaptorPath(NO_VALUE, SMALL_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE) + new TestRaptorPath(ANY, NORMAL, ANY, ANY, ANY, LARGE, ANY), + new TestRaptorPath(ANY, SMALL, ANY, ANY, ANY, ANY, ANY) ) ); assertFalse( comparator.leftDominanceExist( - new TestRaptorPath(NO_VALUE, SMALL_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE), - new TestRaptorPath(NO_VALUE, BIG_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE) + new TestRaptorPath(ANY, NORMAL, ANY, ANY, ANY, LARGE, ANY), + new TestRaptorPath(ANY, LARGE, ANY, ANY, ANY, ANY, ANY) ) ); } @@ -355,20 +135,20 @@ private void verifyStartTimeComparator( /** * Verify that bigger rangeRaptorIterationDepartureTime always wins */ - private void verifyRangeRaptorIterationDepartureTime( + private void verifyIterationDepartureTime( ParetoComparator> comparator ) { // Verify that bigger rangeRaptorIterationDepartureTime always wins assertTrue( comparator.leftDominanceExist( - new TestRaptorPath(BIG_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE), - new TestRaptorPath(SMALL_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE) + new TestRaptorPath(NORMAL, ANY, ANY, ANY, ANY, LARGE, ANY), + new TestRaptorPath(SMALL, ANY, ANY, ANY, ANY, ANY, ANY) ) ); assertFalse( comparator.leftDominanceExist( - new TestRaptorPath(SMALL_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE), - new TestRaptorPath(BIG_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE) + new TestRaptorPath(NORMAL, ANY, ANY, ANY, ANY, LARGE, ANY), + new TestRaptorPath(LARGE, ANY, ANY, ANY, ANY, ANY, ANY) ) ); } @@ -382,14 +162,14 @@ private void verifyEndTimeComparator( // Verify that lower endTime always wins assertTrue( comparator.leftDominanceExist( - new TestRaptorPath(NO_VALUE, NO_VALUE, SMALL_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE), - new TestRaptorPath(NO_VALUE, NO_VALUE, BIG_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE) + new TestRaptorPath(ANY, ANY, NORMAL, ANY, ANY, LARGE, ANY), + new TestRaptorPath(ANY, ANY, LARGE, ANY, ANY, SMALL, ANY) ) ); assertFalse( comparator.leftDominanceExist( - new TestRaptorPath(NO_VALUE, NO_VALUE, BIG_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE), - new TestRaptorPath(NO_VALUE, NO_VALUE, SMALL_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE) + new TestRaptorPath(ANY, ANY, NORMAL, ANY, ANY, LARGE, ANY), + new TestRaptorPath(ANY, ANY, SMALL, ANY, ANY, SMALL, ANY) ) ); } @@ -402,14 +182,14 @@ private void verifyNumberOfTransfers( ) { assertTrue( comparator.leftDominanceExist( - new TestRaptorPath(NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, SMALL_VALUE, NO_VALUE, NO_VALUE), - new TestRaptorPath(NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, BIG_VALUE, NO_VALUE, NO_VALUE) + new TestRaptorPath(ANY, ANY, ANY, ANY, NORMAL, LARGE, ANY), + new TestRaptorPath(ANY, ANY, ANY, ANY, LARGE, SMALL, ANY) ) ); assertFalse( comparator.leftDominanceExist( - new TestRaptorPath(NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, BIG_VALUE, NO_VALUE, NO_VALUE), - new TestRaptorPath(NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, SMALL_VALUE, NO_VALUE, NO_VALUE) + new TestRaptorPath(ANY, ANY, ANY, ANY, NORMAL, LARGE, ANY), + new TestRaptorPath(ANY, ANY, ANY, ANY, SMALL, SMALL, ANY) ) ); } @@ -422,14 +202,14 @@ private void verifyDurationComparator( ) { assertTrue( comparator.leftDominanceExist( - new TestRaptorPath(NO_VALUE, NO_VALUE, NO_VALUE, SMALL_VALUE, NO_VALUE, NO_VALUE, NO_VALUE), - new TestRaptorPath(NO_VALUE, NO_VALUE, NO_VALUE, BIG_VALUE, NO_VALUE, NO_VALUE, NO_VALUE) + new TestRaptorPath(ANY, ANY, ANY, NORMAL, ANY, ANY, ANY), + new TestRaptorPath(ANY, ANY, ANY, LARGE, ANY, ANY, ANY) ) ); assertFalse( comparator.leftDominanceExist( - new TestRaptorPath(NO_VALUE, NO_VALUE, NO_VALUE, BIG_VALUE, NO_VALUE, NO_VALUE, NO_VALUE), - new TestRaptorPath(NO_VALUE, NO_VALUE, NO_VALUE, SMALL_VALUE, NO_VALUE, NO_VALUE, NO_VALUE) + new TestRaptorPath(ANY, ANY, ANY, NORMAL, ANY, ANY, ANY), + new TestRaptorPath(ANY, ANY, ANY, SMALL, ANY, ANY, ANY) ) ); } @@ -440,14 +220,14 @@ private void verifyDurationComparator( private void verifyC1Comparator(ParetoComparator> comparator) { assertTrue( comparator.leftDominanceExist( - new TestRaptorPath(NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, SMALL_VALUE, NO_VALUE), - new TestRaptorPath(NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, BIG_VALUE, NO_VALUE) + new TestRaptorPath(ANY, ANY, ANY, ANY, ANY, NORMAL, ANY), + new TestRaptorPath(ANY, ANY, ANY, ANY, ANY, LARGE, ANY) ) ); assertFalse( comparator.leftDominanceExist( - new TestRaptorPath(NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, BIG_VALUE, NO_VALUE), - new TestRaptorPath(NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, SMALL_VALUE, NO_VALUE) + new TestRaptorPath(ANY, ANY, ANY, ANY, ANY, NORMAL, ANY), + new TestRaptorPath(ANY, ANY, ANY, ANY, ANY, SMALL, ANY) ) ); } @@ -460,34 +240,63 @@ private void verifyRelaxedC1Comparator( ) { assertTrue( comparator.leftDominanceExist( - new TestRaptorPath( - NO_VALUE, - NO_VALUE, - NO_VALUE, - NO_VALUE, - NO_VALUE, - (int) (SMALL_VALUE * (1.4)), - NO_VALUE - ), - new TestRaptorPath(NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, SMALL_VALUE, NO_VALUE) + new TestRaptorPath(ANY, ANY, ANY, ANY, ANY, RELAXED, ANY), + new TestRaptorPath(ANY, ANY, ANY, ANY, ANY, NORMAL, ANY) ) ); assertFalse( comparator.leftDominanceExist( - new TestRaptorPath( - NO_VALUE, - NO_VALUE, - NO_VALUE, - NO_VALUE, - NO_VALUE, - (int) (SMALL_VALUE * (1.6)), - NO_VALUE - ), - new TestRaptorPath(NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, SMALL_VALUE, NO_VALUE) + new TestRaptorPath(ANY, ANY, ANY, ANY, ANY, LARGE, ANY), + new TestRaptorPath(ANY, ANY, ANY, ANY, ANY, NORMAL, ANY) ) ); } + /** + * Verify that relax function is used in the c1 comparator, if and only if c2 is optimal. + */ + private void verifyRelaxedC1IfC2Optimal( + ParetoComparator> comparator + ) { + assertTrue( + comparator.leftDominanceExist( + new TestRaptorPath(ANY, ANY, ANY, ANY, ANY, SMALL, NORMAL), + new TestRaptorPath(ANY, ANY, ANY, ANY, ANY, NORMAL, NORMAL) + ), + "c1 is optimal, c2 is not => path is optimal" + ); + assertTrue( + comparator.leftDominanceExist( + new TestRaptorPath(ANY, ANY, ANY, ANY, ANY, RELAXED, SMALL), + new TestRaptorPath(ANY, ANY, ANY, ANY, ANY, NORMAL, NORMAL) + ), + "c2 is optimal, c1 is within relaxed limit => path is optimal" + ); + assertFalse( + comparator.leftDominanceExist( + new TestRaptorPath(ANY, ANY, ANY, ANY, ANY, RELAXED, ANY), + new TestRaptorPath(ANY, ANY, ANY, ANY, ANY, NORMAL, ANY) + ), + "c2 is not optimal, c1 is within relaxed limit => path is NOT optimal" + ); + assertFalse( + // c2 is optimal, but c1 is not within relaxed limit + comparator.leftDominanceExist( + new TestRaptorPath(ANY, ANY, ANY, ANY, ANY, LARGE, SMALL), + new TestRaptorPath(ANY, ANY, ANY, ANY, ANY, NORMAL, NORMAL) + ), + "c2 is optimal, c1 is not within relaxed limit => path is NOT optimal" + ); + assertFalse( + // c1 and c2 is not optimal (they are equal) + comparator.leftDominanceExist( + new TestRaptorPath(ANY, ANY, ANY, ANY, ANY, NORMAL, NORMAL), + new TestRaptorPath(ANY, ANY, ANY, ANY, ANY, NORMAL, NORMAL) + ), + "c1 and c2 is not optimal" + ); + } + /** * Verify that dominance function is used in a comparator. This method operates on an assumption * that dominance function is l.c2 > r.c2 @@ -496,14 +305,14 @@ private void verifyC2Comparator(ParetoComparator> // Verify that dominance function is used assertTrue( comparator.leftDominanceExist( - new TestRaptorPath(NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, BIG_VALUE), - new TestRaptorPath(NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, SMALL_VALUE) + new TestRaptorPath(ANY, ANY, ANY, ANY, ANY, ANY, SMALL), + new TestRaptorPath(ANY, ANY, ANY, ANY, ANY, ANY, NORMAL) ) ); assertFalse( comparator.leftDominanceExist( - new TestRaptorPath(NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, SMALL_VALUE), - new TestRaptorPath(NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, BIG_VALUE) + new TestRaptorPath(ANY, ANY, ANY, ANY, ANY, ANY, LARGE), + new TestRaptorPath(ANY, ANY, ANY, ANY, ANY, ANY, NORMAL) ) ); } diff --git a/src/test/java/org/opentripplanner/raptor/util/PathStringBuilderTest.java b/src/test/java/org/opentripplanner/raptor/util/PathStringBuilderTest.java index d347f3848e4..771efe6ab03 100644 --- a/src/test/java/org/opentripplanner/raptor/util/PathStringBuilderTest.java +++ b/src/test/java/org/opentripplanner/raptor/util/PathStringBuilderTest.java @@ -71,7 +71,7 @@ public void summary() { @Test public void summaryGeneralizedCostOnly() { - assertEquals("[C₁0.01]", subject.summary(1).toString()); + assertEquals("[C₁0.01 C₂7]", subject.summary(1, 7).toString()); } @Test diff --git a/src/test/java/org/opentripplanner/routing/algorithm/mapping/BikeRentalSnapshotTest.java b/src/test/java/org/opentripplanner/routing/algorithm/mapping/BikeRentalSnapshotTest.java index 3fef2d957b9..988c6c5abf4 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/mapping/BikeRentalSnapshotTest.java +++ b/src/test/java/org/opentripplanner/routing/algorithm/mapping/BikeRentalSnapshotTest.java @@ -89,7 +89,7 @@ public void directBikeRentalArrivingAtDestinationWithDepartAt() { request.journey().setModes(RequestModes.of().withDirectMode(StreetMode.BIKE_RENTAL).build()); request.journey().transit().setFilters(List.of(ExcludeAllTransitFilter.of())); - request.journey().rental().setAllowArrivingInRentedVehicleAtDestination(true); + allowArrivalWithRentalVehicle(request); request.setFrom(p1); request.setTo(p2); @@ -104,7 +104,7 @@ public void directBikeRentalArrivingAtDestinationWithArriveBy() { request.journey().setModes(RequestModes.of().withDirectMode(StreetMode.BIKE_RENTAL).build()); request.journey().transit().setFilters(List.of(ExcludeAllTransitFilter.of())); - request.journey().rental().setAllowArrivingInRentedVehicleAtDestination(true); + allowArrivalWithRentalVehicle(request); request.setFrom(p1); request.setTo(p2); request.setArriveBy(true); @@ -161,4 +161,12 @@ public void egressBikeRental() { expectArriveByToMatchDepartAtAndSnapshot(request); } + + private void allowArrivalWithRentalVehicle(RouteRequest request) { + request.withPreferences(preferences -> + preferences.withBike(bike -> + bike.withRental(rental -> rental.withAllowArrivingInRentedVehicleAtDestination(true)) + ) + ); + } } diff --git a/src/test/java/org/opentripplanner/routing/algorithm/mapping/SnapshotTestBase.java b/src/test/java/org/opentripplanner/routing/algorithm/mapping/SnapshotTestBase.java index bf0e62dbc19..8dbf5536ea2 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/mapping/SnapshotTestBase.java +++ b/src/test/java/org/opentripplanner/routing/algorithm/mapping/SnapshotTestBase.java @@ -36,11 +36,11 @@ import org.opentripplanner.ConstantsForTests; import org.opentripplanner.TestOtpModel; import org.opentripplanner.TestServerContext; -import org.opentripplanner.api.mapping.ItineraryMapper; -import org.opentripplanner.api.model.ApiLeg; import org.opentripplanner.api.parameter.ApiRequestMode; import org.opentripplanner.api.parameter.QualifiedMode; import org.opentripplanner.api.parameter.Qualifier; +import org.opentripplanner.ext.restapi.mapping.ItineraryMapper; +import org.opentripplanner.ext.restapi.model.ApiLeg; import org.opentripplanner.framework.time.TimeUtils; import org.opentripplanner.model.GenericLocation; import org.opentripplanner.model.plan.Itinerary; diff --git a/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/PriorityGroupConfiguratorTest.java b/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/PriorityGroupConfiguratorTest.java index 4cd2b65e8c3..777aee5352c 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/PriorityGroupConfiguratorTest.java +++ b/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/PriorityGroupConfiguratorTest.java @@ -10,66 +10,92 @@ import org.opentripplanner.routing.api.request.request.filter.TransitPriorityGroupSelect; import org.opentripplanner.transit.model.basic.TransitMode; import org.opentripplanner.transit.model.network.RoutingTripPattern; +import org.opentripplanner.transit.model.site.RegularStop; class PriorityGroupConfiguratorTest { - private final TestRouteData routeA = TestRouteData.of( + private static final String AGENCY_A1 = "A1"; + private static final String AGENCY_A2 = "A2"; + private static final String AGENCY_A3 = "A3"; + + private static final int EXP_GROUP_ID_BASE = 1; + private static final int EXP_GROUP_1 = 2; + private static final int EXP_GROUP_2 = 4; + private static final int EXP_GROUP_3 = 8; + + private final TestRouteData routeR1 = route( "R1", TransitMode.RAIL, + AGENCY_A1, List.of(STOP_A, STOP_B), "10:00 10:10" ); - private final TestRouteData routeB = TestRouteData.of( + + private final TestRouteData routeB2 = route( "B2", TransitMode.BUS, + AGENCY_A2, List.of(STOP_B, STOP_D), "10:15 10:40" ); - private final TestRouteData routeC = TestRouteData.of( + private final TestRouteData routeR3 = route( "R3", TransitMode.RAIL, + AGENCY_A3, List.of(STOP_A, STOP_B), "10:00 10:10" ); - private final TestRouteData routeD = TestRouteData.of( - "R3", + private final TestRouteData routeF3 = route( + "F3", TransitMode.FERRY, + AGENCY_A3, + List.of(STOP_A, STOP_B), + "10:00 10:10" + ); + private final TestRouteData routeB3 = route( + "B3", + TransitMode.BUS, + AGENCY_A3, List.of(STOP_A, STOP_B), "10:00 10:10" ); - private final RoutingTripPattern railA = routeA.getTripPattern().getRoutingTripPattern(); - private final RoutingTripPattern busB = routeB.getTripPattern().getRoutingTripPattern(); - private final RoutingTripPattern railC = routeC.getTripPattern().getRoutingTripPattern(); - private final RoutingTripPattern ferryC = routeD.getTripPattern().getRoutingTripPattern(); + private final RoutingTripPattern railR1 = routeR1.getTripPattern().getRoutingTripPattern(); + private final RoutingTripPattern busB2 = routeB2.getTripPattern().getRoutingTripPattern(); + private final RoutingTripPattern railR3 = routeR3.getTripPattern().getRoutingTripPattern(); + private final RoutingTripPattern ferryF3 = routeF3.getTripPattern().getRoutingTripPattern(); + private final RoutingTripPattern busB3 = routeB3.getTripPattern().getRoutingTripPattern(); @Test void emptyConfigurationShouldReturnGroupZero() { var subject = PriorityGroupConfigurator.of(List.of(), List.of()); - assertEquals(0, subject.lookupTransitPriorityGroupId(railA)); - assertEquals(0, subject.lookupTransitPriorityGroupId(busB)); - assertEquals(0, subject.lookupTransitPriorityGroupId(null)); + assertEquals(subject.baseGroupId(), subject.lookupTransitPriorityGroupId(railR1)); + assertEquals(subject.baseGroupId(), subject.lookupTransitPriorityGroupId(busB2)); + assertEquals(subject.baseGroupId(), subject.lookupTransitPriorityGroupId(null)); } @Test - void lookupTransitPriorityGroupIdBySameAgency() { - var subject = PriorityGroupConfigurator.of( - List.of( - TransitPriorityGroupSelect.of().addModes(List.of(TransitMode.BUS)).build(), - TransitPriorityGroupSelect.of().addModes(List.of(TransitMode.RAIL)).build() - ), - List.of() - ); + void lookupTransitPriorityGroupIdByAgency() { + var select = TransitPriorityGroupSelect + .of() + .addModes(List.of(TransitMode.BUS, TransitMode.RAIL)) + .build(); + + // Add matcher `byAgency` for bus and real + var subject = PriorityGroupConfigurator.of(List.of(select), List.of()); - assertEquals(0, subject.lookupTransitPriorityGroupId(null)); - assertEquals(0, subject.lookupTransitPriorityGroupId(ferryC)); - assertEquals(1, subject.lookupTransitPriorityGroupId(railA)); - assertEquals(2, subject.lookupTransitPriorityGroupId(busB)); - assertEquals(1, subject.lookupTransitPriorityGroupId(railC)); + // Agency groups are indexed (group-id set) at request time + assertEquals(EXP_GROUP_ID_BASE, subject.lookupTransitPriorityGroupId(null)); + assertEquals(EXP_GROUP_1, subject.lookupTransitPriorityGroupId(busB2)); + assertEquals(EXP_GROUP_2, subject.lookupTransitPriorityGroupId(railR3)); + assertEquals(EXP_GROUP_3, subject.lookupTransitPriorityGroupId(railR1)); + assertEquals(EXP_GROUP_2, subject.lookupTransitPriorityGroupId(busB3)); + assertEquals(EXP_GROUP_ID_BASE, subject.lookupTransitPriorityGroupId(ferryF3)); } @Test void lookupTransitPriorityGroupIdByGlobalMode() { + // Global groups are indexed (group-id set) at construction time var subject = PriorityGroupConfigurator.of( List.of(), List.of( @@ -78,10 +104,25 @@ void lookupTransitPriorityGroupIdByGlobalMode() { ) ); - assertEquals(0, subject.lookupTransitPriorityGroupId(null)); - assertEquals(0, subject.lookupTransitPriorityGroupId(ferryC)); - assertEquals(2, subject.lookupTransitPriorityGroupId(railA)); - assertEquals(1, subject.lookupTransitPriorityGroupId(busB)); - assertEquals(2, subject.lookupTransitPriorityGroupId(railC)); + assertEquals(EXP_GROUP_ID_BASE, subject.lookupTransitPriorityGroupId(null)); + assertEquals(EXP_GROUP_2, subject.lookupTransitPriorityGroupId(railR1)); + assertEquals(EXP_GROUP_1, subject.lookupTransitPriorityGroupId(busB2)); + assertEquals(EXP_GROUP_2, subject.lookupTransitPriorityGroupId(railR3)); + assertEquals(EXP_GROUP_1, subject.lookupTransitPriorityGroupId(busB3)); + assertEquals(EXP_GROUP_ID_BASE, subject.lookupTransitPriorityGroupId(ferryF3)); + } + + private static TestRouteData route( + String route, + TransitMode mode, + String agency, + List stops, + String times + ) { + return new TestRouteData.Builder(route) + .withMode(mode) + .withAgency(agency) + .withStops(stops) + .build(); } } diff --git a/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/PriorityGroupMatcherTest.java b/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/PriorityGroupMatcherTest.java index 1205b6b2205..880d8bc9b45 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/PriorityGroupMatcherTest.java +++ b/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/PriorityGroupMatcherTest.java @@ -13,7 +13,11 @@ class PriorityGroupMatcherTest { - private final TestRouteData r1 = TestRouteData.rail("R1").withAgency("A1").build(); + private final TestRouteData r1 = TestRouteData + .rail("R1") + .withSubmode("express") + .withAgency("A1") + .build(); private final TestRouteData b1 = TestRouteData.bus("B2").withAgency("A2").build(); private final TestRouteData f1 = TestRouteData .ferry("F1") @@ -42,17 +46,16 @@ void testMode() { @Test void testAgencyIds() { - var matchers = List.of( - PriorityGroupMatcher.of( - TransitPriorityGroupSelect.of().addAgencyIds(List.of(r1agencyId)).build() - ), - PriorityGroupMatcher.of( - TransitPriorityGroupSelect.of().addAgencyIds(List.of(r1agencyId, anyId)).build() - ) + var m1 = PriorityGroupMatcher.of( + TransitPriorityGroupSelect.of().addAgencyIds(List.of(r1agencyId)).build() + ); + var m2 = PriorityGroupMatcher.of( + TransitPriorityGroupSelect.of().addAgencyIds(List.of(r1agencyId, anyId)).build() ); + var matchers = List.of(m1, m2); - assertEquals("AgencyId(F:A1)", matchers.get(0).toString()); - assertEquals("AgencyId(F:A1 | F:ANY)", matchers.get(1).toString()); + assertEquals("AgencyId(F:A1)", m1.toString()); + assertEquals("AgencyId(F:A1 | F:ANY)", m2.toString()); for (PriorityGroupMatcher m : matchers) { assertFalse(m.isEmpty()); @@ -64,17 +67,16 @@ void testAgencyIds() { @Test void routeIds() { - var matchers = List.of( - PriorityGroupMatcher.of( - TransitPriorityGroupSelect.of().addRouteIds(List.of(r1routeId)).build() - ), - PriorityGroupMatcher.of( - TransitPriorityGroupSelect.of().addRouteIds(List.of(r1routeId, anyId)).build() - ) + var m1 = PriorityGroupMatcher.of( + TransitPriorityGroupSelect.of().addRouteIds(List.of(r1routeId)).build() ); + var m2 = PriorityGroupMatcher.of( + TransitPriorityGroupSelect.of().addRouteIds(List.of(r1routeId, anyId)).build() + ); + var matchers = List.of(m1, m2); - assertEquals("RouteId(F:R1)", matchers.get(0).toString()); - assertEquals("RouteId(F:R1 | F:ANY)", matchers.get(1).toString()); + assertEquals("RouteId(F:R1)", m1.toString()); + assertEquals("RouteId(F:R1 | F:ANY)", m2.toString()); for (PriorityGroupMatcher m : matchers) { assertFalse(m.isEmpty()); @@ -98,9 +100,31 @@ void testSubMode() { assertFalse(subject.match(bus)); } + @Test + void testAnd() { + var subject = PriorityGroupMatcher.of( + TransitPriorityGroupSelect + .of() + .addSubModeRegexp(List.of("express")) + .addRouteIds(List.of(r1routeId)) + .addModes(List.of(TransitMode.RAIL, TransitMode.TRAM)) + .build() + ); + + assertEquals( + "(Mode(RAIL | TRAM) & SubModeRegexp(express) & RouteId(F:R1))", + subject.toString() + ); + + assertFalse(subject.isEmpty()); + assertTrue(subject.match(rail1)); + assertFalse(subject.match(ferry)); + assertFalse(subject.match(bus)); + } + @Test void testToString() { - var m = PriorityGroupMatcher.of( + var subject = PriorityGroupMatcher.of( TransitPriorityGroupSelect .of() .addModes(List.of(TransitMode.BUS, TransitMode.TRAM)) @@ -111,8 +135,8 @@ void testToString() { ); assertEquals( - "(Mode(BUS | TRAM) | SubModeRegexp(.*local.*) | AgencyId(F:A1 | F:ANY) | RouteId(F:R1))", - m.toString() + "(Mode(BUS | TRAM) & SubModeRegexp(.*local.*) & AgencyId(F:A1 | F:ANY) & RouteId(F:R1))", + subject.toString() ); } } diff --git a/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/services/OptimizePathDomainServiceTest.java b/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/services/OptimizePathDomainServiceTest.java index d05a4090b39..be927046c43 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/services/OptimizePathDomainServiceTest.java +++ b/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/services/OptimizePathDomainServiceTest.java @@ -74,6 +74,7 @@ public void testTripWithoutTransfers() { var original = pathBuilder() .access(ITERATION_START_TIME, STOP_B, D1m) .bus(trip1, STOP_C) + .c2(345) .egress(D1m); var subject = subject(transfers, null); diff --git a/src/test/java/org/opentripplanner/routing/api/request/preference/BikePreferencesTest.java b/src/test/java/org/opentripplanner/routing/api/request/preference/BikePreferencesTest.java index e8e3ff576a9..9da7852cc2c 100644 --- a/src/test/java/org/opentripplanner/routing/api/request/preference/BikePreferencesTest.java +++ b/src/test/java/org/opentripplanner/routing/api/request/preference/BikePreferencesTest.java @@ -21,6 +21,8 @@ class BikePreferencesTest { .withSlope(1) .build(); public static final BicycleOptimizeType OPTIMIZE_TYPE = BicycleOptimizeType.TRIANGLE; + public static final int RENTAL_PICKUP_TIME = 30; + public static final int PARK_COST = 30; private final BikePreferences subject = BikePreferences .of() @@ -32,6 +34,8 @@ class BikePreferencesTest { .withSwitchTime(SWITCH_TIME) .withSwitchCost(SWITCH_COST) .withOptimizeType(OPTIMIZE_TYPE) + .withRental(rental -> rental.withPickupTime(RENTAL_PICKUP_TIME).build()) + .withParking(parking -> parking.withParkCost(PARK_COST).build()) .withOptimizeTriangle(it -> it.withSlope(1).build()) .build(); @@ -80,6 +84,18 @@ void optimizeTriangle() { assertEquals(TRIANGLE, subject.optimizeTriangle()); } + @Test + void rental() { + var vehicleRental = VehicleRentalPreferences.of().withPickupTime(RENTAL_PICKUP_TIME).build(); + assertEquals(vehicleRental, subject.rental()); + } + + @Test + void parking() { + var vehicleParking = VehicleParkingPreferences.of().withParkCost(PARK_COST).build(); + assertEquals(vehicleParking, subject.parking()); + } + @Test void testOfAndCopyOf() { // Return same object if no value is set @@ -107,6 +123,8 @@ void testToString() { "walkingReluctance: 1.45, " + "switchTime: 3m20s, " + "switchCost: $450, " + + "parking: VehicleParkingPreferences{parkCost: $30}, " + + "rental: VehicleRentalPreferences{pickupTime: 30s}, " + "optimizeType: TRIANGLE, " + "optimizeTriangle: TimeSlopeSafetyTriangle[time=0.0, slope=1.0, safety=0.0]" + "}", diff --git a/src/test/java/org/opentripplanner/routing/api/request/preference/CarPreferencesTest.java b/src/test/java/org/opentripplanner/routing/api/request/preference/CarPreferencesTest.java index 7bc0a1620ab..c81cb41d883 100644 --- a/src/test/java/org/opentripplanner/routing/api/request/preference/CarPreferencesTest.java +++ b/src/test/java/org/opentripplanner/routing/api/request/preference/CarPreferencesTest.java @@ -17,6 +17,8 @@ class CarPreferencesTest { private static final double ACCELERATION_SPEED = 3.1; private static final double DECELERATION_SPEED = 3.5; public static final int DROPOFF_TIME = 450; + public static final int RENTAL_PICKUP_TIME = 30; + public static final int PARK_COST = 30; private final CarPreferences subject = CarPreferences .of() @@ -27,6 +29,8 @@ class CarPreferencesTest { .withDropoffTime(DROPOFF_TIME) .withAccelerationSpeed(ACCELERATION_SPEED) .withDecelerationSpeed(DECELERATION_SPEED) + .withRental(rental -> rental.withPickupTime(RENTAL_PICKUP_TIME).build()) + .withParking(parking -> parking.withParkCost(PARK_COST).build()) .build(); @Test @@ -64,6 +68,18 @@ void decelerationSpeed() { assertEquals(DECELERATION_SPEED, subject.decelerationSpeed()); } + @Test + void rental() { + var vehicleRental = VehicleRentalPreferences.of().withPickupTime(RENTAL_PICKUP_TIME).build(); + assertEquals(vehicleRental, subject.rental()); + } + + @Test + void parking() { + var vehicleParking = VehicleParkingPreferences.of().withParkCost(PARK_COST).build(); + assertEquals(vehicleParking, subject.parking()); + } + @Test void testCopyOfEqualsAndHashCode() { // Return same object if no value is set @@ -83,6 +99,8 @@ void testToString() { "CarPreferences{" + "speed: 20.0, " + "reluctance: 5.1, " + + "parking: VehicleParkingPreferences{parkCost: $30}, " + + "rental: VehicleRentalPreferences{pickupTime: 30s}, " + "pickupTime: 600, " + "pickupCost: $500, " + "dropoffTime: 450, " + diff --git a/src/test/java/org/opentripplanner/routing/api/request/preference/VehicleRentalPreferencesTest.java b/src/test/java/org/opentripplanner/routing/api/request/preference/VehicleRentalPreferencesTest.java index 402b885529c..6092c8139bc 100644 --- a/src/test/java/org/opentripplanner/routing/api/request/preference/VehicleRentalPreferencesTest.java +++ b/src/test/java/org/opentripplanner/routing/api/request/preference/VehicleRentalPreferencesTest.java @@ -4,6 +4,7 @@ import static org.junit.jupiter.api.Assertions.assertSame; import static org.opentripplanner.routing.api.request.preference.ImmutablePreferencesAsserts.assertEqualsAndHashCode; +import java.util.Set; import org.junit.jupiter.api.Test; class VehicleRentalPreferencesTest { @@ -14,6 +15,10 @@ class VehicleRentalPreferencesTest { public static final int DROPOFF_COST = 450; public static final int ARRIVE_IN_RENTAL_COST = 500; public static final boolean USE_AVAILABILITY_INFORMATION = true; + public static final boolean ALLOW_ARRIVING_IN_RENTED_VEHICLE = true; + public static final Set ALLOWED_NETWORKS = Set.of("foo"); + public static final Set BANNED_NETWORKS = Set.of("bar"); + private final VehicleRentalPreferences subject = VehicleRentalPreferences .of() .withPickupTime(PICKUP_TIME) @@ -22,6 +27,9 @@ class VehicleRentalPreferencesTest { .withDropoffCost(DROPOFF_COST) .withArrivingInRentalVehicleAtDestinationCost(ARRIVE_IN_RENTAL_COST) .withUseAvailabilityInformation(USE_AVAILABILITY_INFORMATION) + .withAllowArrivingInRentedVehicleAtDestination(ALLOW_ARRIVING_IN_RENTED_VEHICLE) + .withAllowedNetworks(ALLOWED_NETWORKS) + .withBannedNetworks(BANNED_NETWORKS) .build(); @Test @@ -54,6 +62,25 @@ void arrivingInRentalVehicleAtDestinationCost() { assertEquals(ARRIVE_IN_RENTAL_COST, subject.arrivingInRentalVehicleAtDestinationCost()); } + @Test + void allowArrivingInRentedVehicleAtDestination() { + assertEquals( + ALLOW_ARRIVING_IN_RENTED_VEHICLE, + subject.allowArrivingInRentedVehicleAtDestination() + ); + } + + @Test + void allowedNetworks() { + assertEquals(ALLOWED_NETWORKS, subject.allowedNetworks()); + } + + @Test + void bannedNetworks() { + assertEquals(BANNED_NETWORKS, subject.bannedNetworks()); + } + + @Test void testOfAndCopyOf() { // Return same object if no value is set assertSame(VehicleRentalPreferences.DEFAULT, VehicleRentalPreferences.of().build()); @@ -78,7 +105,10 @@ void testToString() { "dropoffTime: 45s, " + "dropoffCost: $450, " + "useAvailabilityInformation, " + - "arrivingInRentalVehicleAtDestinationCost: 500.0" + + "arrivingInRentalVehicleAtDestinationCost: 500.0, " + + "allowArrivingInRentedVehicleAtDestination, " + + "allowedNetworks: [foo], " + + "bannedNetworks: [bar]" + "}", subject.toString() ); diff --git a/src/test/java/org/opentripplanner/routing/core/RoutingPreferencesTest.java b/src/test/java/org/opentripplanner/routing/core/RoutingPreferencesTest.java index 8131fdd1299..c67d539e902 100644 --- a/src/test/java/org/opentripplanner/routing/core/RoutingPreferencesTest.java +++ b/src/test/java/org/opentripplanner/routing/core/RoutingPreferencesTest.java @@ -24,7 +24,6 @@ public void copyOfShouldReturnTheSameInstanceWhenBuild() { assertSame(pref.wheelchair(), copy.wheelchair()); assertSame(pref.transit(), copy.transit()); assertSame(pref.street(), copy.street()); - assertSame(pref.rental(), copy.rental()); assertSame(pref.itineraryFilter(), copy.itineraryFilter()); assertSame(pref.system(), copy.system()); } @@ -110,16 +109,6 @@ public void copyOfWithStreetChanges() { assertNotSame(pref.street(), copy.street()); } - @Test - public void copyOfWithRentalChanges() { - var pref = new RoutingPreferences(); - var copy = pref.copyOf().withRental(r -> r.withDropoffCost(2)).build(); - - assertNotSame(pref, copy); - assertNotSame(pref.rental(), copy.rental()); - assertSame(pref.itineraryFilter(), copy.itineraryFilter()); - } - @Test public void copyOfWithItineraryFilterChanges() { var pref = new RoutingPreferences(); diff --git a/src/test/java/org/opentripplanner/smoketest/PortlandSmokeTest.java b/src/test/java/org/opentripplanner/smoketest/PortlandSmokeTest.java index f55810283ca..9881b6eb0a2 100644 --- a/src/test/java/org/opentripplanner/smoketest/PortlandSmokeTest.java +++ b/src/test/java/org/opentripplanner/smoketest/PortlandSmokeTest.java @@ -1,27 +1,35 @@ package org.opentripplanner.smoketest; +import static org.junit.jupiter.api.Assertions.assertFalse; import static org.opentripplanner.client.model.RequestMode.SCOOTER_RENT; import static org.opentripplanner.client.model.RequestMode.TRAM; +import static org.opentripplanner.client.model.RequestMode.TRANSIT; import static org.opentripplanner.client.model.RequestMode.WALK; +import java.io.IOException; import java.util.List; import java.util.Set; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; import org.junit.jupiter.params.provider.ValueSource; import org.opentripplanner.client.model.Coordinate; +import org.opentripplanner.client.parameters.TripPlanParameters; +import org.opentripplanner.smoketest.util.RequestCombinationsBuilder; import org.opentripplanner.smoketest.util.SmokeTestRequest; @Tag("smoke-test") @Tag("portland") public class PortlandSmokeTest { - Coordinate cennentenial = new Coordinate(45.504602, -122.4968719); - Coordinate buckman = new Coordinate(45.51720, -122.652289867); - Coordinate hazelwood = new Coordinate(45.52463, -122.5583); - Coordinate piedmont = new Coordinate(45.5746, -122.6697); - Coordinate mountTaborPark = new Coordinate(45.511399, -122.594203); + static final Coordinate cennentenial = new Coordinate(45.504602, -122.4968719); + static final Coordinate buckman = new Coordinate(45.51720, -122.652289867); + static final Coordinate hazelwood = new Coordinate(45.52463, -122.5583); + static final Coordinate piedmont = new Coordinate(45.5746, -122.6697); + static final Coordinate mountTaborPark = new Coordinate(45.511399, -122.594203); @Test public void railTrip() { @@ -35,25 +43,48 @@ public void railTrip() { SmokeTest.assertThatAllTransitLegsHaveFareProducts(plan); } - /** - * Checks that a scooter rental finishes at the edge of the park area and is continued on - * foot rather than scootering all the way to the destination. - */ - @ParameterizedTest(name = "scooter rental in a geofencing zone with arriveBy={0}") - @ValueSource(booleans = { true, false }) - public void geofencingZone(boolean arriveBy) { - SmokeTest.basicRouteTest( - new SmokeTestRequest(buckman, mountTaborPark, Set.of(SCOOTER_RENT, WALK), arriveBy), - List.of("WALK", "SCOOTER", "WALK") - ); + static List buildCombinations() { + return new RequestCombinationsBuilder() + .withLocations(cennentenial, buckman, hazelwood, piedmont, mountTaborPark) + .withModes(TRANSIT, WALK) + .withTime(SmokeTest.weekdayAtNoon()) + .includeWheelchair() + .includeArriveBy() + .build(); } - @ParameterizedTest(name = "scooter rental with arriveBy={0}") - @ValueSource(booleans = { true, false }) - void scooterRent(boolean arriveBy) { - SmokeTest.basicRouteTest( - new SmokeTestRequest(cennentenial, piedmont, Set.of(SCOOTER_RENT, WALK), arriveBy), - List.of("WALK", "SCOOTER") - ); + @ParameterizedTest + @MethodSource("buildCombinations") + public void accessibleRouting(TripPlanParameters params) throws IOException { + var tripPlan = SmokeTest.API_CLIENT.plan(params); + assertFalse(tripPlan.transitItineraries().isEmpty()); + SmokeTest.assertThatAllTransitLegsHaveFareProducts(tripPlan); + } + + @Nested + @Disabled("Disabled because it seems that the rental services have closed for the winter") + class GeofencingZones { + + /** + * Checks that a scooter rental finishes at the edge of the park area and is continued on + * foot rather than scootering all the way to the destination. + */ + @ParameterizedTest(name = "scooter rental in a geofencing zone with arriveBy={0}") + @ValueSource(booleans = { true, false }) + public void geofencingZone(boolean arriveBy) { + SmokeTest.basicRouteTest( + new SmokeTestRequest(buckman, mountTaborPark, Set.of(SCOOTER_RENT, WALK), arriveBy), + List.of("WALK", "SCOOTER", "WALK") + ); + } + + @ParameterizedTest(name = "scooter rental with arriveBy={0}") + @ValueSource(booleans = { true, false }) + void scooterRent(boolean arriveBy) { + SmokeTest.basicRouteTest( + new SmokeTestRequest(cennentenial, piedmont, Set.of(SCOOTER_RENT, WALK), arriveBy), + List.of("WALK", "SCOOTER") + ); + } } } diff --git a/src/test/java/org/opentripplanner/street/integration/BikeRentalTest.java b/src/test/java/org/opentripplanner/street/integration/BikeRentalTest.java index 634c10863da..0694a991069 100644 --- a/src/test/java/org/opentripplanner/street/integration/BikeRentalTest.java +++ b/src/test/java/org/opentripplanner/street/integration/BikeRentalTest.java @@ -433,8 +433,14 @@ private void assertNoRental( Set allowedNetworks ) { Consumer setter = options -> { - options.journey().rental().setAllowedNetworks(allowedNetworks); - options.journey().rental().setBannedNetworks(bannedNetworks); + options.withPreferences(preferences -> + preferences.withBike(bike -> + bike.withRental(rental -> { + rental.withAllowedNetworks(allowedNetworks); + rental.withBannedNetworks(bannedNetworks); + }) + ) + ); }; assertEquals( @@ -457,8 +463,14 @@ private void assertPathWithNetwork( Set allowedNetworks ) { Consumer setter = options -> { - options.journey().rental().setAllowedNetworks(allowedNetworks); - options.journey().rental().setBannedNetworks(bannedNetworks); + options.withPreferences(preferences -> + preferences.withBike(bike -> + bike.withRental(rental -> { + rental.withAllowedNetworks(allowedNetworks); + rental.withBannedNetworks(bannedNetworks); + }) + ) + ); }; assertEquals( @@ -580,17 +592,15 @@ private List runStreetSearchAndCreateDescriptor( toVertex, arriveBy, options -> { - options.withPreferences(p -> - p.withRental(rental -> - rental - .withUseAvailabilityInformation(useAvailabilityInformation) - .withArrivingInRentalVehicleAtDestinationCost(keepRentedBicycleCost) + options.withPreferences(preferences -> + preferences.withBike(bike -> + bike.withRental(rental -> { + rental.withUseAvailabilityInformation(useAvailabilityInformation); + rental.withArrivingInRentalVehicleAtDestinationCost(keepRentedBicycleCost); + rental.withAllowArrivingInRentedVehicleAtDestination(keepRentedBicycleCost > 0); + }) ) ); - options - .journey() - .rental() - .setAllowArrivingInRentedVehicleAtDestination(keepRentedBicycleCost > 0); } ); } @@ -605,14 +615,16 @@ private List runStreetSearchAndCreateDescriptor( request.setArriveBy(arriveBy); + optionsSetter.accept(request); + request.withPreferences(preferences -> - preferences.withRental(rental -> - rental.withPickupTime(42).withPickupCost(62).withDropoffCost(33).withDropoffTime(15) + preferences.withBike(bike -> + bike.withRental(rental -> + rental.withPickupTime(42).withPickupCost(62).withDropoffCost(33).withDropoffTime(15) + ) ) ); - optionsSetter.accept(request); - return runStreetSearchAndCreateDescriptor( fromVertex, toVertex, diff --git a/src/test/java/org/opentripplanner/street/model/edge/VehicleRentalEdgeTest.java b/src/test/java/org/opentripplanner/street/model/edge/VehicleRentalEdgeTest.java index 8cdb0bf3ed8..84f5efcc1c5 100644 --- a/src/test/java/org/opentripplanner/street/model/edge/VehicleRentalEdgeTest.java +++ b/src/test/java/org/opentripplanner/street/model/edge/VehicleRentalEdgeTest.java @@ -10,7 +10,6 @@ import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.opentripplanner.routing.api.request.StreetMode; -import org.opentripplanner.routing.api.request.request.VehicleRentalRequest; import org.opentripplanner.service.vehiclerental.model.GeofencingZone; import org.opentripplanner.service.vehiclerental.model.RentalVehicleType; import org.opentripplanner.service.vehiclerental.model.TestVehicleRentalStationBuilder; @@ -219,15 +218,18 @@ private void initEdgeAndRequest( vehicleRentalEdge = VehicleRentalEdge.createVehicleRentalEdge(vertex, RentalFormFactor.BICYCLE); - var rentalRequest = new VehicleRentalRequest(); this.request = StreetSearchRequest .of() .withMode(mode) - .withRental(rentalRequest) .withPreferences(preferences -> preferences - .withRental(rental -> rental.withUseAvailabilityInformation(useRealtime).build()) + .withCar(car -> + car.withRental(rental -> rental.withUseAvailabilityInformation(useRealtime)) + ) + .withBike(bike -> + bike.withRental(rental -> rental.withUseAvailabilityInformation(useRealtime)) + ) .build() ) .build(); diff --git a/src/test/java/org/opentripplanner/street/search/state/TestStateBuilder.java b/src/test/java/org/opentripplanner/street/search/state/TestStateBuilder.java index 042ff5ba553..a4dbf76e55e 100644 --- a/src/test/java/org/opentripplanner/street/search/state/TestStateBuilder.java +++ b/src/test/java/org/opentripplanner/street/search/state/TestStateBuilder.java @@ -1,6 +1,7 @@ package org.opentripplanner.street.search.state; import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.opentripplanner.routing.algorithm.raptoradapter.router.street.AccessEgressType.EGRESS; import static org.opentripplanner.transit.model.site.PathwayMode.WALKWAY; import java.time.Instant; @@ -10,6 +11,7 @@ import javax.annotation.Nonnull; import org.opentripplanner.framework.i18n.I18NString; import org.opentripplanner.framework.i18n.NonLocalizedString; +import org.opentripplanner.routing.algorithm.raptoradapter.router.street.AccessEgressType; import org.opentripplanner.routing.api.request.StreetMode; import org.opentripplanner.service.vehiclerental.model.TestFreeFloatingRentalVehicleBuilder; import org.opentripplanner.service.vehiclerental.model.TestVehicleRentalStationBuilder; @@ -20,6 +22,7 @@ import org.opentripplanner.street.model.RentalFormFactor; import org.opentripplanner.street.model.StreetTraversalPermission; import org.opentripplanner.street.model._data.StreetModelForTest; +import org.opentripplanner.street.model.edge.Edge; import org.opentripplanner.street.model.edge.ElevatorAlightEdge; import org.opentripplanner.street.model.edge.ElevatorBoardEdge; import org.opentripplanner.street.model.edge.ElevatorHopEdge; @@ -51,10 +54,19 @@ public class TestStateBuilder { private State currentState; private TestStateBuilder(StreetMode mode) { + this(mode, AccessEgressType.ACCESS); + } + + private TestStateBuilder(StreetMode mode, AccessEgressType type) { currentState = new State( StreetModelForTest.intersectionVertex(count, count), - StreetSearchRequest.of().withMode(mode).withStartTime(DEFAULT_START_TIME).build() + StreetSearchRequest + .of() + .withArriveBy(type.isEgress()) + .withMode(mode) + .withStartTime(DEFAULT_START_TIME) + .build() ); } @@ -80,6 +92,14 @@ public static TestStateBuilder ofScooterRental() { return new TestStateBuilder(StreetMode.SCOOTER_RENTAL); } + /** + * Creates a state that starts the scooter rental in arriveBy mode, so starting with + * a rental scooter and going backwards until it finds a rental vertex where to drop it. + */ + public static TestStateBuilder ofScooterRentalArriveBy() { + return new TestStateBuilder(StreetMode.SCOOTER_RENTAL, EGRESS); + } + public static TestStateBuilder ofBikeRental() { return new TestStateBuilder(StreetMode.BIKE_RENTAL); } @@ -248,7 +268,12 @@ private TestStateBuilder arriveAtStop(RegularStop stop) { var from = (StreetVertex) currentState.vertex; var to = new TransitStopVertexBuilder().withStop(stop).build(); - var edge = StreetTransitStopLink.createStreetTransitStopLink(from, to); + Edge edge; + if (currentState.getRequest().arriveBy()) { + edge = StreetTransitStopLink.createStreetTransitStopLink(to, from); + } else { + edge = StreetTransitStopLink.createStreetTransitStopLink(from, to); + } var states = edge.traverse(currentState); if (states.length != 1) { throw new IllegalStateException("Only single state transitions are supported."); diff --git a/src/test/java/org/opentripplanner/transit/model/timetable/ScheduledTripTimesTest.java b/src/test/java/org/opentripplanner/transit/model/timetable/ScheduledTripTimesTest.java index ed6c5c70f92..e2c1148ef51 100644 --- a/src/test/java/org/opentripplanner/transit/model/timetable/ScheduledTripTimesTest.java +++ b/src/test/java/org/opentripplanner/transit/model/timetable/ScheduledTripTimesTest.java @@ -13,6 +13,7 @@ import org.opentripplanner.framework.time.TimeUtils; import org.opentripplanner.transit.model._data.TransitModelForTest; import org.opentripplanner.transit.model.basic.Accessibility; +import org.opentripplanner.transit.model.framework.DataValidationException; import org.opentripplanner.transit.model.framework.FeedScopedId; class ScheduledTripTimesTest { @@ -102,7 +103,7 @@ void isTimepoint() { @Test void validateLastArrivalTimeIsNotMoreThan20DaysAfterFirstDepartureTime() { var ex = assertThrows( - IllegalArgumentException.class, + DataValidationException.class, () -> ScheduledTripTimes .of() @@ -111,7 +112,10 @@ void validateLastArrivalTimeIsNotMoreThan20DaysAfterFirstDepartureTime() { .withTrip(TRIP) .build() ); - assertEquals("The value is not in range[-43200, 1728000]: 1728001", ex.getMessage()); + assertEquals( + "The arrivalTime is not in range[-12h, 20d]. Time: 10:00:01+20d, stop-pos: 2, trip: F:Trip-1.", + ex.getMessage() + ); } @Test diff --git a/src/test/resources/org/opentripplanner/graph_builder/module/islandpruning/matinkyla-escalator.pbf b/src/test/resources/org/opentripplanner/graph_builder/module/islandpruning/matinkyla-escalator.pbf new file mode 100644 index 00000000000..bcae465ae99 Binary files /dev/null and b/src/test/resources/org/opentripplanner/graph_builder/module/islandpruning/matinkyla-escalator.pbf differ